2017-08-04 29 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()方法的实现细节。

相关问题