Java 明显的类型冲突,但编译
下面的代码段为什么要编译Java 明显的类型冲突,但编译,java,generics,Java,Generics,下面的代码段为什么要编译OtherInterface不扩展Concrete,所以我敢打赌这不会编译。但确实如此 public class Test { public static interface SomeInterface {} public static interface OtherInterface{} public static class Concrete implements SomeInterface { public <T
OtherInterface
不扩展Concrete
,所以我敢打赌这不会编译。但确实如此
public class Test {
public static interface SomeInterface {}
public static interface OtherInterface{}
public static class Concrete implements SomeInterface {
public <T extends Concrete> T getConcrete() {
return null;
}
}
public static void doStuff() {
Concrete c = new Concrete();
OtherInterface iCompile = c.getConcrete();
}
}
公共类测试{
公共静态接口SomeInterface{}
公共静态接口OtherInterface{}
公共静态类具体实现了SomeInterface{
公共混凝土{
返回null;
}
}
公共静态void doStuff(){
混凝土c=新混凝土();
OtherInterface iCompile=c.getConcrete();
}
}
另一方面,下一个代码段不会编译,这正是我所期望的
public class Test {
public static interface SomeInterface {}
public static class UnrelatedClass{}
public static class Concrete implements SomeInterface {
public <T extends Concrete> T getConcrete() {
return null;
}
}
public static void doStuff() {
Concrete c = new Concrete();
UnrelatedClass iCompile = c.getConcrete();
}
}
公共类测试{
公共静态接口SomeInterface{}
公共静态类未更新类{}
公共静态类具体实现了SomeInterface{
公共混凝土{
返回null;
}
}
公共静态void doStuff(){
混凝土c=新混凝土();
UnrelatedClass iCompile=c.getConcrete();
}
}
区别在于:
public static interface OtherInterface{} ...
OtherInterface iCompile = c.getConcrete();
vs
含义:在第一种情况下,调用方法返回某个接口的实例。接口可以是任何类
在第二个示例中,您指示返回的类型是一个特定的类!一个已知的类,不实现另一个接口
以及错误消息:
原因:不存在上界为UnrelatedClass,Concrete的类型变量T的唯一最大实例
这是非常具体的
换句话说:编译器在赋值的左侧考虑因素,以确定有效的类型。而UnrelatedClass
永远不能是具体的——因为类UnrelatedClass
不扩展具体的
而SomeInterface
的东西也可以实现OtherInterface
@azurefrog,第二个没有为我编译(我不是OP),错误消息是t
的上限(这是具体的)与未更新类
不匹配。编译的类可能与此问题中的相同:。编译器推断出一个交集类型Concrete&OtherInterface
@Jerome我链接到的Q&A中的答案解释了它。关键是可能有一个类扩展了Concrete
并实现了OtherInterface
,理论类型就是T
所推断的类型。我认为秘密在于返回null。因为您没有给出任何特定的类型来查看编译器,所以编译器耸耸肩(隐喻地说)并将问题进一步向下推。我和Jorn Vernee在一起-可能有一个类扩展了Concrete
并实现了OtherInterface
,而“null”并没有提供足够的信息让编译器争论。您正在解释为什么第二个代码段没有编译,这很好,但我已经知道了。但这并不能真正解释为什么第一个会这样做。如果getConcrete()
不是泛型的,返回的是具体的,那么第一个代码段将无法编译。嗯?第一个示例返回某个接口的实例。实际的类未知,很可能正在实现另一个接口。
public static class UnrelatedClass{} ...
UnrelatedClass iCompile = c.getConcrete();