我經常發現一些使用泛型在Java中這樣的代碼:Java中Java泛型:特殊用法<T擴展對象及接口>
public static <T extends Object & Interface> foo(T object) {
...
}
由於從對象類每類inherites我不知道如果extends Object
給出特殊含義或用於特殊目的。任何人都可以告訴我,如果有不同的背景使用這或當你採取<T extends Interface>
隱含給出?
我經常發現一些使用泛型在Java中這樣的代碼:Java中Java泛型:特殊用法<T擴展對象及接口>
public static <T extends Object & Interface> foo(T object) {
...
}
由於從對象類每類inherites我不知道如果extends Object
給出特殊含義或用於特殊目的。任何人都可以告訴我,如果有不同的背景使用這或當你採取<T extends Interface>
隱含給出?
<T extends Object & Interface>
這Object
顯然是多餘的,通常等於
<T extends Interface>
注意,使用Interface
作爲類名稱強烈勸阻。
爲什麼非常灰心?只是好奇。 SomeClass.Interface用於我們的項目,它工作得很好。 – momomo
@momo已經有一個關鍵詞叫'interface',所以人們可能會混淆,一個真正的類永遠不會是一個'Interface' :)。來到你的代碼中,'SomeClass.Interface',那裏有什麼'Interface'? –
感謝您的回覆。這不是我項目的代碼,接口名稱只是一個例子。 –
正如您所指出的,任何T
無論如何都會隱含擴展Object
。明確定義T extends Object
是完全多餘的,您可以(也可能應該)將其刪除,並且只需定義T extends Interface
。
這個可能有必要讓你的代碼向後兼容二進制級別。假設你有以下的實用工具類:
public class Utils {
public static <T> int length(T obj) {
if(obj instanceof CharSequence) {
return ((CharSequence)obj).length();
}
return 0;
}
}
它發佈爲一個圖書館和一些像這樣的應用中:
public class Main {
public static void main(String... args) {
System.out.println(Utils.length("foo"));
}
}
工作正常。然而,後來你決定限制你的方法只適用於其他對象的接口CharSequence
的實現,它總是返回0,似乎沒有人使用你的方法與非CharSequence參數。所以,你改變了簽名
public static <T extends CharSequence> int length(T obj) { ... }
現在,如果你鏈接Main
類與庫的新版本,它將失敗,java.lang.NoSuchMethodError
。這是因爲擦除了您的方法的簽名已更改。之前它是int length(Object obj)
,但現在是int length(CharSequence obj)
。如果您重新編譯Main
類,它將正常工作,但並不總是可以重新編譯所有現有的代碼。這樣的伎倆可以執行:
public static <T extends Object & CharSequence> int length(T obj) { ... }
現在,你實際上是限制參數CharSequence
接口,但擦除簽名回int length(Object obj)
(擦除類型始終處於A & B & C & ...
鏈中的第一個,它的正式記錄),所以Utils
類的新版本與舊代碼二進制兼容。
我很好奇,你在哪裏「經常」找到這段代碼? – Tunaki
請提供該方法的*精確*簽名,而不是人爲示例。你的'foo'缺少返回類型,不會編譯。我也有強烈的感覺,爭論不僅僅是'T',而是'List'。如果您指出您看到此類方法的位置,這也很好。我想我可以回答爲什麼這是必要的,但我需要確切的細節。 –
@TagirValeev你是不對的。它只是T.我在Michael Inden的書「Der Weg zum Java-Profi」中找到了這個例子。當然,原始代碼中有一個return語句。我的問題只是關於標籤。不過謝謝。 –