【发布时间】:2017-03-21 10:40:46
【问题描述】:
我有课
class Holder<SomeType extends AbstractType>{
SomeType createType(){...}
}
然后在它之外,我打电话
Holder holder = new Holder<MyType>();
我不知道如何实现 createType() 方法。
我尝试了在 StackOverflow 和网络中可以找到的所有内容,但我总是在同一个死胡同中运行: 在运行时,如果我这样做了
TypeVariable typeVariable = getClass().getTypeParameters()[0];
System.err.println("typeVariable "+typeVariable);
我得到的是“SomeType”而不是“MyType”,所以我无法获取适当的构造函数,因为我想使用 Class.forName("MyType") 而不是 Class.forName("SomeType") 导致java.lang.ClassNotFoundException
我使用 SomeType extends AbstractType,所以我知道我所有的 MyTypes 都将具有相同的可用构造函数。
我不能用
ParameterizedType t = (ParameterizedType) MyClass.class.getGenericSuperclass();
因为 Holder 不是任何有用的子类
我可以在我的 Holder 类中做这样的事情,但我正在寻找一种无需在构造函数中传递参数即可使用反射的方法
private final Class<SomeType> type;
public Holder(Class<SomeType> type) {
this.type = type;
}
尝试我在网上看到的所有各种想法感觉就像我在追逐我的尾巴,所以我想我在这里遗漏了一个明显的元素。
感谢您的帮助!
编辑:我无法像Create instance of generic type in Java? 那样解决它 我不能将类作为 createType(Class) 的参数传递,因为在调用 createType 时我不知道该类(当我不知道我的类型时,此方法应该创建适当类型的子类)孩子们应该是)
【问题讨论】:
-
由于类型擦除,调用
new Holder<MyType>()的泛型类型在运行时是未知的,因此您所能做的就是以某种方式传递该信息,例如通过传入类型类。或者,您可以创建子类,例如class MyTypeHolder extends Holder<MyType>在这种情况下你可以use reflection to extract the generic type。 -
或许你可以将createType的声明改为
T createType(Class extends AbstractType> clz) {} 然后像SomeType sType = (SomeType)holder.createType(MyType.班级);这样,Holder 类就不必是通用的。 -
你指的是
.class.newInstance()吗? -
谢谢 Thomas,我尝试了我的方法来摆脱 20 多个 MyType1Holder、MyType2Holder... 我想我只需要在 Holder 的构造函数中传递类以避免类型擦除。我会回复而不是评论,我可以投票赞成你的答案;)
标签: java generics reflection