考虑以下 Java 代码:
public class Program {
static class Value {
public String getString() {
return "value";
}
}
static class BetterValue extends Value {
public String getBetterString() {
return "better_value";
}
}
static class Container<V extends Value> {
public final V value;
// EDIT #2: to mitigate the NPE:
public Container(V value) {
this.value = value;
}
}
static class BetterContainter<V extends BetterValue> extends Container<V> {
// EDIT #2: to mitigate the NPE:
public BetterContainter(V value) {
super(value);
}
}
public static void main(String[] args) {
// EDIT #2: to mitigate the NPE:
Container container = new Container(new Value());
System.out.println(container.value.getString());
// EDIT #2: to mitigate the NPE:
BetterContainter betterContainer = new BetterContainter(new BetterValue());
System.out.println(betterContainer.value.getBetterString());
}
}
当我尝试编译时,我得到:
Error:(28, 49) java: cannot find symbol
symbol: method getBetterString()
location: variable value of type V
BetterContainer 中的“value”字段不应该删除为 BetterValue 吗?为什么它会删除容器的值?
编辑:为了减轻“不使用原始类型”的争论并使问题更接近我实际处理的问题,假设添加以下代码:
static class Consumer<C extends Container> {
protected final C container;
public Consumer(C container) {
this.container = container;
}
public void consume() {
System.out.println(container.getValue().getValue());
}
}
static class BetterConsumer<C extends BetterContainer> extends Consumer<C> {
public BetterConsumer(C container) {
super(container);
}
@Override
public void consume() {
System.out.println(container.getValue().getBetterValue());
}
}
我该如何解决能够做到的事情
System.out.println(container.getValue().getBetterValue());
没有类型转换?
最佳答案
@Slaw 的回答解释了原因:当使用原始类型时,Container 类中的 V 字段将被删除为 Value,即使它是从 BetterContainer 访问的。
要解决您的消费者示例的问题,您需要向消费者类添加一个类型变量(本例中为 ? 通配符):
static class Consumer<C extends Container<?>> {
protected final C container;
public Consumer(C container) {
this.container = container;
}
public void consume() {
System.out.println(container.value.getString());
}
}
static class BetterConsumer<C extends BetterContainer<?>> extends Consumer<C> {
public BetterConsumer(C container) {
super(container);
}
@Override
public void consume() {
System.out.println(container.value.getBetterString());
}
}
虽然在您的示例中没有必要,但您也可以使用绑定(bind)类型变量:
static class Consumer<T extends Value, C extends Container<T>> {
关于java - 为什么这个泛型类型没有删除到指定的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60927255/