2015-09-26 85 views
4

我經常發現一些使用泛型在Java中這樣的代碼:Java中Java泛型:特殊用法<T擴展對象及接口>

public static <T extends Object & Interface> foo(T object) { 
    ... 
} 

由於從對象類每類inherites我不知道如果extends Object給出特殊含義或用於特殊目的。任何人都可以告訴我,如果有不同的背景使用這或當你採取<T extends Interface>隱含給出?

+2

我很好奇,你在哪裏「經常」找到這段代碼? – Tunaki

+0

請提供該方法的*精確*簽名,而不是人爲示例。你的'foo'缺少返回類型,不會編譯。我也有強烈的感覺,爭論不僅僅是'T',而是'List '。如果您指出您看到此類方法的位置,這也很好。我想我可以回答爲什麼這是必要的,但我需要確切的細節。 –

+0

@TagirValeev你是不對的。它只是T.我在Michael Inden的書「Der Weg zum Java-Profi」中找到了這個例子。當然,原始代碼中有一個return語句。我的問題只是關於標籤。不過謝謝。 –

回答

5
<T extends Object & Interface> 

Object顯然是多餘的,通常等於

<T extends Interface> 

注意,使用Interface作爲類名稱強烈勸阻。

+0

爲什麼非常灰心?只是好奇。 SomeClass.Interface用於我們的項目,它工作得很好。 – momomo

+0

@momo已經有一個關鍵詞叫'interface',所以人們可能會混淆,一個真正的類永遠不會是一個'Interface' :)。來到你的代碼中,'SomeClass.Interface',那裏有什麼'Interface'? –

+0

感謝您的回覆。這不是我項目的代碼,接口名稱只是一個例子。 –

0

正如您所指出的,任何T無論如何都會隱含擴展Object。明確定義T extends Object是完全多餘的,您可以(也可能應該)將其刪除,並且只需定義T extends Interface

0

這個可能有必要讓你的代碼向後兼容二進制級別。假設你有以下的實用工具類:

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類的新版本與舊代碼二進制兼容。

相關問題