2017-08-04 51 views
0

我想知道,是否以及如何能夠實現以下,而只有beeing能夠使用兩類文字變量:如何從兩個現有的類文字構造一個參數化的類文字?

Class<Foo<Bar>> getFoobar(){ 

    Class<Foo> fooClass = Foo.class; 
    Class<Bar> barClass = Bar.class; 

    // ... combine and return Class<Foo<Bar>> 
} 

...與限制,這是不可能的儘量使用類型,但可以從類文字變量中以編程方式檢索類型。

+1

如果我已經正確理解了你,不,我不認爲這是可能的,因爲你試圖返回一個不存在的類型......沒有類型>因爲該信息是動態綁定的。不是100%確定。 –

+2

...因此,爲了澄清,我們是否假設您有一個類「Foo」,其泛型類型是Bar,並且您在包含'Foo'和'Bar'的各個類型的'Class'之後? –

+0

@J史密斯是的,你是對的。 –

回答

1

從字面上看,我們不能使用類型參數,即我們不能期望像T.classnew T()這樣的表達式能夠工作,因爲我們無法用「編程方式」對泛型進行太多處理。參數化類型失去它們的類型參數編譯後,從而爲Foo<T>類型的以下實例:

Foo<String> foostr...; 
Foo<Bar> foobar...; 

我們將具有相同的Class對象,即

foostr.getClass() == foobar.getClass() == Foo.class 

因此存在允許類文字沒有意義如Foo<String>.classFoo<Bar>.class

這是編譯型的背後泛型類型的諸多限制的原因:因爲有大約類型參數在運行時沒有任何信息(因爲類型擦除),我們在編譯時限制很多的可能性。

一種可能性在運行時與通用類型的工作是提取關於類Foo和作爲ParameterizedType對象其類型參數Bar,例如信息

class Bar { 
    ... 
} 

class Foo<T> { 
    ... 
} 

class Foobar extends Foo<Bar> { 

    ParameterizedType getFoobar() { 
    return (ParameterizedType)getClass().getGenericSuperclass(); 
    } 
} 

... 

Foobar foobar = new Foobar(); 
System.out.println(foobar.getFoobar().getRawType()); // Foo.class 
System.out.println(foobar.getFoobar().getActualTypeArguments()[0]); // Bar.class 

另一種方法這是基於第一位的,但更容易實現,是TypeReference使用(或創建自己的類)從FasterXML Jacson項目捕捉參數化類型:

class Foo<T> { ... } 

class Bar { ... } 

TypeReference typeReference = new TypeReference<Foo<Bar>>() {}; 
ParameterizedTypeImpl parametrizedType = (ParameterizedTypeImpl) typeReference.getType(); 
System.out.println(parametrizedType.getTypeName()); // Foo<Bar> 
System.out.println(parametrizedType.getRawType()); // Foo 
System.out.println(parametrizedType.getActualTypeArguments()[0]); // Bar 

查看ParameterizedTypeImpl#toString()方法的實現細節。

相關問題