Java 为什么在编译时不检查多绑定泛型
假设我有这样的简单类Java 为什么在编译时不检查多绑定泛型,java,generics,interface,extension-methods,Java,Generics,Interface,Extension Methods,假设我有这样的简单类 public interface Something{ public void doSomtehing() } class A{ public int getAVal(){ return 0; } } class AWithSomething extends A implements Something{ public void doSomething{ //in fact do nothing, HAHA
public interface Something{
public void doSomtehing()
}
class A{
public int getAVal(){
return 0;
}
}
class AWithSomething extends A implements Something{
public void doSomething{
//in fact do nothing, HAHA
}
}
abstract class B{
public abstract <T extends A & Something> T getAWithSomething()
}
class C extends B{
//allowed??? gives warnig about unchecked conversion
public A getAWithSomething {
return new A();
}
}
class D extends B{
//same unchecked warning
public AWithSomething getAWithSomething(){
return new AWithSomething();
}
}
C c = new C();
//not implemented but seems valid
c.getAWithSomething().doSomething();
D d = new D();
d.getAWithSomething().doSomething();
JLS称之为。应该允许库实现者在不中断客户端(C
)的情况下泛化其API(B
)。事实上,可以用List
替换B
,getAWithSomething()
替换get(int)
,C
替换为定制的List
实现,例如apache commonsFixedSizeList
方法签名中的类型变量被擦除为原始类或接口类型。B.getAWithSomething()
中的类型变量T
被擦除到其最左边的绑定A
。迁移兼容性基于生成的方法签名A getAWithSomething()
。这意味着重写getAWithSomething()
的子类必须声明a
的返回类型或其子类型
请注意,您会收到一条警告:“小心,您正在将
a
作为a&Something
传递,这可能会出错”。它可能会:在返回的A
上调用doSomething()
将抛出ClassCastException
,因为A
不能被转换到某物舒尔?它不应该至少是一个A
,或者它必须只有A
中的所有方法吗?如果这是真的,为什么它不能同时拥有来自某物的所有方法呢?如果B
中的Api获取C
对象并尝试调用doSomething()
,它将中断。这真的是有意的吗?@RafaelT希望你所有的附加问题现在都得到解决。所以我可以阅读你的答案,因为“多个有界泛型返回类型是完全无用的(至少到现在为止),因为它们确保了什么都没有,实现者可以随意打破它”??@RafaelT一个人可以这样看待它。实现者可以自由地打破类型契约。但是,如果编译器强制执行类型约定,实现者仍然可以通过无限循环、抛出异常等方式打破约定。不过,大多数实现者不会这样做。舒尔。但如果实现者循环无限,我将永远不会得到返回,因此他会破坏代码。我已经听到了关于我构建的非白痴感知API的抱怨。。。
class C extends B{
//not allowed!
public Something getAWithSomething {
return new Something(){
doSomething(){}
};
}
}