我有一个类代表一对相同类型的两个值(类型可以是任何特定类型的集合):
public class Pair<E extends AClass>{
private E var1;
private E var2;
}
Run Code Online (Sandbox Code Playgroud)
这个类由框架使用,因此它需要一个无参构造函数,我必须在其中实例化2个变量(var1,var2):
public class Pair<E extends AClass>{
private E var1;
private E var2;
public Pair(){
var1 = invoke constructor of type E;
var2 = invoke constructor of type E
}
}
Run Code Online (Sandbox Code Playgroud)
这里显然有很多问题:
为了实例化变量,我应该以某种方式知道它的确切类型并调用该特定类型的构造函数; 在最好的情况下,这意味着在构造函数中有一个非常大的if else语句,如:
public Pair(){
if(var1 instanceof SpecificType1){
var1 = new SpecificType1();
var2 = new SpecificType2();
}
}
Run Code Online (Sandbox Code Playgroud)即使我如上所述,我也会遇到一些问题,因为var1被声明为E类,我在尝试实例化SpecficType1并将结果对象分配给var1/var2时会遇到类型不匹配错误.为了使它工作,我必须转向E:
var1 = (E)new SpecificType1();
Run Code Online (Sandbox Code Playgroud)但是这会破坏编译时类型检查,因为我正在尝试将特定类型转换为泛型类型.
这是Java中Generics的限制还是这个场景对于使用Generics来说是一个糟糕的局面?
为了实例化变量,我应该以某种方式知道它的确切类型并调用该特定类型的构造函数; 在最好的情况下,这意味着在构造函数中有一个非常大的if else语句,如:
在此之前你会遇到问题.
if(var1 instanceof SpecificType1){
var1 = new SpecificType1();
var2 = new SpecificType2();
}
Run Code Online (Sandbox Code Playgroud)
var1就是null在这一点上,所以var1 instanceof T是false对所有T.
Java泛型的一个限制是擦除了泛型类型参数,因此无法从零参数构造函数中反映出类型参数.
调用者提供一些背景来告诉你如何初始化var1和var2,并提供这方面的典型方式是通过构造函数参数.
您最好的选择可能是让var1并var2开始null然后延迟初始化,直到您可以获得所需的上下文.
也许
void init(Class<E> type) {
if (type.isAssignableFrom(ConcreteType1.class)) {
var1 = type.cast(new ConcreteType1(...));
var2 = type.cast(new ConcreteType1(...));
} else { /* other branches */ }
}
Run Code Online (Sandbox Code Playgroud)
这是不完美的,因为你仍然无法区分E extends List<String>,E extends List<Number>但它可能足够你的情况,并且该.cast方法将为您提供类型安全的演员E.
或者,Guava,Guice和相关库提供类似Supplier<E>接口的东西,它可以在init方法中派上用场.
| 归档时间: |
|
| 查看次数: |
1035 次 |
| 最近记录: |