我有一个班级
class Holder<SomeType extends AbstractType>{
SomeType createType(){...}
}
然后在它之外,我打电话
Holder holder = new Holder<MyType>();
我无法弄清楚如何实现createType()方法。
我尝试了在StackOverflow和网络上找到的所有内容,但我总是在同一个死胡同中运行: 在运行时,如果我这样做
TypeVariable typeVariable = getClass().getTypeParameters()[0];
System.err.println("typeVariable "+typeVariable);
我得到了#34; SomeType&#34;而不是&#34; MyType&#34;,因此我无法获取相应的构造函数,因为我想使用Class.forName(&#34; MyType&#34;)而不是Class.forName(&#34) ; SomeType&#34;)导致java.lang.ClassNotFoundException
我使用SomeType扩展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时我不会知道该类(当我无法调用时,此方法应该创建适当类型的子类)已知我的孩子应该是哪种类型)
答案 0 :(得分:0)
就像托马斯在评论中所说,Java使用类型擦除。这意味着填充SomeType
的具体类型不会隐式传递给Holder
。但要实例化一个类,您需要该类型信息。因此,您必须将该信息明确传递给Holder
。有几种方法可以做到这一点,其中一种是你找到的。在构建它时,Class
对象传递给Holder
。
Java 8引入了方法引用,也允许您引用构造函数:
Function<String, MyType> cons = MyType::new;
这将创建一个功能接口Function
的实例,其具有方法apply
,该方法需要String
并返回MyType
。
然后,您可以将此仿函数传递给Holder
的构造函数,并保存以在createType
中使用:
class Holder<SomeType extends AbstractType>{
private final Function<String, SomeType> cons;
public Holder(Function<String, SomeType> cons) {
this.cons = cons;
...
}
SomeType createType() {
return cons.apply("SomeString");
}
}
这比使用Class
以同样方式的优点是,您在编译时知道构造函数的签名,并且没有抛出异常。