public class PairJ<T> {
private T first;
private T second;
public PairJ(T first, T second) {
this.first = first;
this.second = second;
}
public T first() {
return this.first;
}
public T second() {
return this.second;
}
public <R> Pair<R> replaceFirst(R newFirst) {
return new Pair(newFirst, second());
}
}
class Vehicle {}
class Car extends Vehicle {}
class Tank extends Vehicle {}
代码可以编译。 但是当我这样做时:
PairJ<Car> twoCars = new PairJ(new Car(), new Car());
Tank actuallyACar = twoCars.replaceFirst(new Tank()).second();
它仍然可以编译,但在运行时会给出强制转换异常,因为该对中的第二个元素是汽车,而不是坦克。
所以我把它改成这样:
public <R, T extends R> Pair<R> replaceFirst(R newFirst) {
return new Pair(newFirst, second());
}
但是这段代码仍然可以编译并给出相同的异常:
PairJ<Car> twoCars = new PairJ(new Car(), new Car());
Tank actuallyACar = twoCars.replaceFirst(new Tank()).second();
似乎 T extends R 的声明在这里不起作用。
如何在这里强制执行类型安全?
更具体地说,我如何确保 java 推断
twoCars.replaceFirst(new Tank())
返回一对车辆而不是一对坦克?因此,当我尝试将其第二个元素分配给 Tank 类型的变量时,会出现编译时错误?并减少出现运行时异常的机会?
编辑:
在 Scala 中,我们可以这样做:
class Pair[T](val first: T, val second: T) {
def replaceFirst[R >: T](newFirst: R): Pair[R] = new Pair[R](newFirst, second)
}
[R >: T] 确保 R 是 T 的基类型,我们如何在 Java 中做同样的事情?
最佳答案
how can I make sure that java infers
twoCars.replaceFirst(new Tank())
to return a Pair of Vehicle instead of a Pair of tanks?
显式提供类型参数
twoCars.<Vehicle>replaceFirst(new Tank())
尝试调用时会出现编译器错误
Tank actuallyACar = twoCars.<Vehicle>replaceFirst(new Tank()).second();
关于Java 泛型 : how to declare a generic parameter as the base type of another generic parameter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24338511/