2010-05-06 60 views
13

Java方法調用,可以設定參數下面的代碼:什麼時候參數化方法調用有用?

class Test 
{ 
    <T> void test() 
    { 
    } 

    public static void main(String[] args) 
    { 
     new Test().<Object>test(); 
     //   ^^^^^^^^ 
    } 
} 

我發現這是可能從Eclipse的Java格式化設置對話框,並想知道是否有任何情況下,這是有用的或必需的。


編輯

基於阿恩的出色答卷,我想出了以下結論:

除了改善型安全性阿恩的例子說明了一個參數化方法調用,您可以指定的應該是容器元素類型的方法參數的公共基類型。這種類型通常由編譯器自動推斷爲最具體的通用基本類型。通過參數化方法調用,該行爲可能被覆蓋。如果編譯器推導出多個通用類型,則可能需要參數化方法調用。

下面的示例演示該行爲:

import java.util.Arrays; 
import java.util.List; 

class Test 
{ 
    public static void main(String[] args) 
    { 
     Integer a=new Integer(0); 
     Long b=new Long(0); 
     List<Object> listError=Arrays.asList(a, b); 
     //error because Number&Comparable<?> is not Object 
     List<Object> listObj=Arrays.<Object>asList(a, b); 
     List<Number> listNum=Arrays.<Number>asList(a, b); 
     List<Comparable<?>> listCmp=Arrays.<Comparable<?>>asList(a, b); 
    } 
} 

這種行爲是在Java語言規範第三版第8.4.4和15.12.2.7定義,但不容易理解。

+0

難道只有我認爲這很奇怪嗎?這個線程中的每個人似乎都認爲「參數化方法」必須是一個通用方法?具有聲明參數的方法是「參數化」方法。泛型方法只是另一種參數化方法,其中類型就是這樣一個參數。或者我錯過了什麼? – 2017-09-22 13:24:49

+0

你是在現場!事後看來,標題應該是「什麼時候調用類型參數的方法調用不可能推斷有用?」 – 2017-09-23 16:51:02

回答

13

我從來沒有在實踐中使用這個,但你能想象使用這種類型的安全性。請看下面的方法:

<T> void method(T... items) { 
    List<T> list = new ArrayList<T>(); 
    for (T item : items) 
     list.add(item); 
    System.out.println(list); 
} 

你可以這樣調用它:

o.<Object>method("Blah", new Long(0)); 
o.<Number>method(new Integer(100), new Long(0)); 

但是,這將引發一個編譯器錯誤:

o.<Number>method("String", new Long(0)); 

所以,你有一個通用的方法是類型安全並且可以用於每個對象,而不限於特定的接口或類。

+0

優秀的答案,尤其是使用可變參數 – 2010-05-09 17:18:39

8

這可能是最有用的,當你正在採取某種類型的集合,並返回該集合的一些子集。

<T> List<T> filter(Collection<? extends T> coll, Predicate<? super T> pred) { 
    List<T> returnList = new ArrayList<T>(); 
    for(T t : coll) { 
     if(pred.matches(t)){ 
      returnList.add(t); 
     } 
    } 
    return returnList; 
} 

編輯:

更一般地,只要你想返回一個特定的類型,或者你想在一個通用的方式來鏈接類型的兩個或多個參數是有益的。

+1

您沒有在該代碼中的任何位置執行參數化方法調用 – newacct 2010-05-06 17:47:10

13

參數化方法調用在您希望允許不需要轉換的情況下允許不同類型時非常有用。例如,Collections輔助類大量使用參數化方法調用。當你想使用他們的輔助方法之一,舉幾個例子一個新的通用集合:

List<String> anEmptyStringList = Collections.<String>emptyList(); 
Set<Integer> unmodifiableCopy = Collections.<Integer>unmodifiableSet(originalSet); 

所以,當你希望能夠在其他地方使用泛型類型,要使用這些方法調用。它們在使用泛型時防止編譯器警告。

+1

不是從變量聲明中推斷的集合類型嗎? – 2010-05-06 14:32:40

+0

如果你在列表中沒有參數,列出 anEmptyStringList = Collections.emptyList()',你將從編譯器得到一個強制性警告(除非你關閉了它們)。事實上,我首先從一位向我展示如何擺脫警告的同事那裏瞭解到這一點。 – justkt 2010-05-06 14:35:43

+0

我無法在我的設置上重現該警告。即使使用-Xlint參數。這可能是由於編譯器的差異造成的。我使用Linux上Sun JDK的javac 1.6.0_20。 – 2010-05-06 15:02:21

1

例如,當你需要一些比較普遍方法

public static <T extends Comparable> T max(T one, T two) { 
    if (one.compareTo(two) > 0) { 
     return one; 
    } else { 
     return two; 
    } 
} 
+1

假設該方法是類聚合的成員,並且一般類型參數T被加入到可比在聲明然後我可以調用它簡單地稱爲 Aggregator.max(新的整數(5),新的整數(10)); 通話中不需要參數。 – 2010-05-06 15:08:35

+0

您沒有在該代碼中的任何地方執行參數化方法調用 – newacct 2010-05-06 17:47:26

+0

是的,同意。不需要另外指定類。 – 2010-05-06 21:46:48

相關問題