我有一个带有泛型参数的类,由于各种原因,我需要与该参数关联的具体类,所以我想接受它作为构造函数的一部分,例如:
public class Foo<T> {
private final Class<T> clazz;
public Foo(Class<T> clazz) {
this.clazz = clazz;
}
}
我还有其他一些类,我想用它来构造它,也可以参数化,例如:
public class MyObj<T> { /* stuff */ }
当我尝试使用Foo<T>
创建MyObj
时,我似乎无法计算出要编译的参数。例如这失败了:
Foo<MyObj<?>> foo = new Foo<MyObj<?>>(MyObj.class);
发生编译时错误,如:
构造函数
Foo<MyObj<?>>(Class<MyObj>)
未定义
同样,当我为MyObj
提供具体类型时,事情仍然失败:
Foo<MyObj<String>> foo = new Foo<MyObj<String>>(MyObj.class);
发生编译时错误,如:
构造函数
Foo<MyObj<String>>(Class<MyObj>)
未定义
我怀疑Foo
的构造函数参数在我的Foo
定义或我的构造函数调用中是不正确的,但我不确定如何修改类型参数。< / p>
我该如何解决这个问题?
答案 0 :(得分:2)
Class
无法表示参数化类型。相同的Class
对象将MyObj<String>
表示为MyObj<Integer>
(或者更确切地说没有MyObj<String>
类型的对象,只有MyObj
类型的对象,泛型是编译时功能,它们不会在运行时定义对象。
如果你只是一个非通用的
class MyObj {}
你可以简单地做
Foo<MyObj> foo = new Foo<>(MyObj.class);
但是,由于您的类型是通用的,并且您似乎想要维护其类型参数的类型,因此您需要更进一步。你需要类型代币。
Guava提供了一个可以使用的TypeToken
课程。您必须将Foo
更改为
class Foo<T> {
final Type type;
public Foo(Type type) {
this.type = type;
}
}
然后
Foo<MyObj<String>> foo = new Foo<MyObj<String>>(new TypeToken<MyObj<String>>() {}.getType());
现在,如果您打印出type
,就会看到
com.example.MyObj<java.lang.String>
如果将其强制转换为ParameterizedType
,则可以检索其参数化。
但请注意,您无法在此处获得类型安全性。你可能不小心写了
Foo<MyObj<String>> foo = new Foo<MyObj<String>>(new TypeToken<MyObj<Integer>>() {}.getType());
它会编译好。
答案 1 :(得分:0)
我会这样做:
Foo<MyObj> foo = new Foo<MyObj>(MyObj.class);
如果我真的知道你试图解决的更高级问题是什么,我可以给出更好的建议。但我必须与之合作的是&#34; Foo&#34;和&#34; MyObj&#34;