表观类型违规,但编译

时间:2017-07-03 14:26:21

标签: java generics

为什么下面的代码片段会编译? 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();
    }
}

另一方面,下一个片段无法编译,这正是我所期望的。

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

1 个答案:

答案 0 :(得分:5)

区别在于:

public static interface OtherInterface{} ...
OtherInterface iCompile = c.getConcrete();

VS。

public static class UnrelatedClass{} ...
UnrelatedClass iCompile = c.getConcrete();

含义:在第一种情况下,您调用该方法返回某个接口的实例。接口可以是任何类。

在第二个示例中,您指示返回的类型是特定的类!一个已知的类,实现其他接口!

错误信息:

  

原因:类型变量T没有唯一的最大实例,上限为UnrelatedClass,Concrete

在这里非常具体。

换句话说:编译因素在该分配的左侧 - 确定有效类型。并且UnrelatedClass 永远不会成为Concrete - 因为课程UnrelatedClass 延伸Concrete

SomeInterface的某些内容以及实施OtherInterface