2012-08-09 117 views
5

我想知道只有當方法是靜態時才使用泛型方法嗎?對於非靜態的你可以定義一個泛型類,你不需要它是通用的方法。那是對的嗎 ?Java:泛型方法只與靜態?

例如,

public class Example<E>{ 

     //this is suffice with no compiler error 
     public void doSomething(E [] arr){ 
       for(E item : arr){ 
        System.out.println(item); 
       } 
     } 

     //this wouldn't be wrong, but is it necessary ? 
     public <E> doSomething(E [] arr){ 
       for(E item : arr){ 
        System.out.println(item); 
       } 
     } 
    } 

,而編譯器將強制添加類型參數,使其成爲通用的方法,如果它是靜態的。

public static <E> doSomething(E [] arr){ 


    } 

我不知道我是否正確。

+4

你也可以擁有通用的實例方法,而不需要使你的類成爲通用的。 – 2012-08-09 14:17:19

回答

4
public class Example<E>{ 

爲實例的方法和字段定義了一個通用類型。

public void <E> doSomething(E [] arr){ 

這定義了第二個E,它與第一個不同,可能會造成混淆。

注:void仍需要;)

靜態字段和方法不使用泛型類的。

public static <F> doSomething(F [] arr) { } 

private static final List<E> list = new ArrayList<>(); // will not compile. 
+0

靜態字段和方法不使用類的通用類型。這是爲什麼 ? – peter 2012-08-09 14:31:44

+0

類的每個實例都可以具有不同的通用類型。這對靜態成員沒有意義。 – 2012-08-09 14:33:29

+0

非靜態字段和方法呢?他們是否共享班級的通用類型?我的意思是他們必須? – peter 2012-08-09 14:43:42

3

假設您聲明Example<String> example = new Example<String>();

  • public void doSomething(E [] arr)將期待一String[]參數
  • public <E> void doSomething(E [] arr)將期望的任何類型的陣列(它是不一樣的EExample<E>
  • public static <E> void doSomething(E [] arr)將期望的任何類型的陣列

在任何情況下,由於您的Example<E>可以參數化,所以您不能在該靜態調用中使用該E,因爲它將與實例相關。這有點像從靜態方法中調用非靜態成員。所以你必須在本地重新定義它。

+0

你可以例如創建一個'Example ',然後創建一個'Example '。靜態方法與特定實例無關,但與類相關。所以靜態方法無法解決'E',因爲可能有幾個。 – assylias 2012-08-09 14:38:16

+0

我的比喻是,如果你有一個'private String abc;'(一個實例字段),你不能從靜態方法訪問它,因爲每個類的實例都有一個'abc'字符串。 – assylias 2012-08-09 14:39:06

+0

那麼在這種情況下,我必須使用E以外的其他東西嗎?如果我使用E,它會給編譯器錯誤嗎?你在本地重新定義它的意義是什麼 – peter 2012-08-09 14:40:03

0

考慮接口java.util.Collection。它被聲明爲:

public interface Collection<E>{ 
    //... 
    <T> T[] toArray(T[] a); 
} 

toArray是使用類型參數T,這與從接口聲明的類型參數E沒有任何關係的普通實例方法。

這是JDK本身的一個很好的例子,它說明了使用泛型實例方法的價值。