2017-07-03 22 views
14

爲什麼下面的代碼片段編譯? 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(); 
    } 
} 
+0

@azurefrog第二個不爲我編譯(我不是OP),錯誤消息是他'T'(它是'Concrete')的上限與'UnrelatedClass'不匹配。 – Tom

+0

@azurefrog,湯姆的評論是我有 – Jerome

+2

編譯的可能是在這個問題相同:https://stackoverflow.com/questions/29670018/why-can-this-generic-method-with-a-束縛返回任何類型。編譯器推斷一個交集類型'Concrete&OtherInterface'。 – Radiodef

回答

5

這裏的區別是:

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

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

含義:在第一種情況下,調用該方法返回的一些接口的一個實例。接口可以是任何類。

在第二個例子,你指示即返回類型是具體類的!一個已知的類,而且不是實現那個其他接口!

和錯誤消息:

原因:沒有唯一的最大實例存在與上界UnrelatedClass類型變量T,混凝土

是非常具體的在這裏。

換句話說:編譯器因素在該賦值的左側 - 確定有效類型。並且UnrelatedClass可以從不Concrete - 因爲UnrelatedClass不是延伸Concrete

雖然SomeInterface可以以及實施OtherInterface

+1

你正在解釋爲什麼第二個代碼片段不能編譯,這很好,但我已經知道了。這並不能解釋爲什麼第一個人會這樣做。如果'getConcrete()'不是泛型的並且返回混亂,則第一個代碼片段不會編譯。 – Jerome

+1

咦?第一個示例返回某個接口的實例。實際的類是未知的,並且很可能正在實現其他接口。 – GhostCat