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();