2015-10-17 50 views
2

我有這樣額外的類型參數避免無效的覆蓋錯誤?

public interface AnInterface { 
    Consumer<Object> getConsumer(); 
} 

一個接口和一個實現類像

public class AClass implements AnInterface { 
    @Override 
    public Consumer<String> getConsumer() { 
     return System.out::println; 
    } 
} 

這(正確),因爲Consumer<String>不會編譯沒有延伸Consumer<Object>

不過,如果我更改接口以對getConsumer一個額外的,未使用的類型參數,該錯誤消失,並罰款編譯:

<T> Consumer<Object> getConsumer(); 

這是怎麼回事?

這發生在JDK 1.8 u20中的javac和Luna中的Eclipse編譯器中。

+0

感謝非常好的問題。 –

+0

奇怪,它不首先編譯,你應該能夠覆蓋更具體的類型作爲返回,擴展(可分配給)原始類型http://stackoverflow.com/questions/14694852/can-overridden-方法 - 不同於回報類型 – Hurda

+0

@Hurda,這是不一樣的。 –

回答

3

代碼編譯,當您添加類型參數<T>,就是在這種情況下,你要替換原料getConsumer()方法的原因,即你是不是重新定義的類型參數(<T>),但你我只是無視它而已。

值得一提的是,延長原料類或壓倒一切的原始方法時,整個通用信息恰恰忽略了,這意味着,在這種情況下,編譯器將無法驗證是否重寫方法的類型參數(<String> )與抽象方法的類型參數(<Object>)兼容。

如果你有保持的方法,一般的,它看起來像:

@Override 
public <T> Consumer<String> getConsumer() { 
    ... 
} 

,然後編譯器會糾正喚醒一個編譯時錯誤。

+0

我以爲這樣的事情可能會發生,但我很困惑,因爲它不應該是一個錯誤,我的班級不會那麼真的沒有實現接口?你有鏈接到關於這是如何工作的更多信息? – takteek

+0

等一下,它怎麼樣?它似乎具體約束。 – Makoto

+0

@Makoto,如果一個方法定義了一個類型參數(不管返回類型是否爲泛型),該方法是通用的。當接口的抽象方法定義了一個類型參數,但實現方法不關心它(即忽略它),那麼實現方法是未知的。當一個方法被認爲是原始的,那麼編譯器會忽略整個通用信息(包括返回類型中的一個)。但是,這不適用於只返回泛型類型並且不實現其他方法的方法。 –

0

,你應該這樣寫:

public interface AnInterface<T> { 
    Consumer<T> getConsumer(); 
} 

public class AClass implements AnInterface<String> { 
    @Override 
    public Consumer<String> getConsumer { 
     return System.out::println; 
    } 
} 
+0

打我吧:) –

+1

是的,這是正確的做法,但這並沒有真正解決*爲什麼*其他形式的作品。 – Makoto

+0

...這是我的答案試圖:) –