2016-09-18 206 views
0

我真的很抱歉,因爲我認爲我瞭解通用但我不知道,對我感到羞恥。T是參數類型還是類類型?

什麼這兩個

public static <T> void c(T obj) { 
    System.out.println(obj.toString()); 
} 

public static <T> void d(List<T> obj) { 
    System.out.println(obj.toString()); 
} 

之間的差作爲

List <Integer> l1 = Arrays.asList(new Integer[]{1,2,3}); 
Gen.c(l1); 
Gen.d(l1); 

返回相同的輸出 [1,2,3]

作爲List<T> obj與T obj表現相同。

T表示參數類型類別/對象

+2

你爲什麼期望他們的行爲有所不同?在這兩種情況下,你都要在列表中調用toString。在c中,你將它稱爲T類型的對象,這恰好是一個列表。在d中,你將它作爲List傳入列表中。 –

+0

這個例子的問題是它實際上並不需要泛型(你可以簡單地使參數類型爲Object),所以很難看出它們爲什麼不同。儘管試圖將不是'List'的東西傳遞給'd',但這不起作用,但它對'c'起作用。 –

+0

嗨,謝謝,有沒有辦法告訴我這些論據本身是不同的? –

回答

2

c的情況下,您的T可以是任何東西,其中包括一個列表。但是因爲Java不知道它是什麼,所以你不能對它做任何列表特定的操作。

d的情況下,您的T必須是一個列表。因爲Java知道它是什麼,所以可以執行諸如添加和刪除以及迭代等操作。

1

<T><T extends Object完全相同。所以T可以是從Object延伸的任何東西,這是Java中的每個類。例如,您可以編寫<T extends Animal>,然後您可以將從Animal延伸的所有內容(如CatDog)。重要的是,在該方法中,您只知道它是某種類型的Animal。因此,即使您爲該方法提供了Dog類型的對象,您也不會有CatDog特定方法。您只能使用Animal的方法。

事實上,這隻能將視圖限制在給定對象上,如casting。看到這個例子:

Dog dog = new Dog(); 
dog.bark(); // Works as it is a dog 
Animal dogAsAnimal = (Animal) dog; 
dogAsAnimal.bark(); // Does not compile, dogAsAnimal is restricted to Animal though it is a Dog 

在你的例子中也是這樣。方法c接受從Object延伸的任何T,所以每個對象在Java。方法d接受List<T>類型的對象。這些是僅包含T類型元素的List對象。在這種情況下,T意味着T extends Object。所以d接受List s其中包含Object s。

好的,泛型有什麼好處?您可以限制對象只能使用修復類型TT可以是任意的,但一旦選擇就會修復。
看一看Javas List class。在仿製藥之前,您可以將任何東西放在List之內,如CatsDogs。你將不得不編碼一個特殊的DogList implements List類,以便只允許DogsLists。現在您可以編碼一個List類並將其限制爲一個變量T。看看這個例子:

List<Dog> dogList = new LinkedList<Dog>(); 
dogList.add(new Dog()); // Works fine 
dogList.add(new Cat()); // Does not compile, Cat is no Dog 
List<Animal> animalList = new LinkedList<Animal>(); 
animalList.add(new Dog()); // Works 
animalList.add(new Cat()); // Also works 

但我們只用一個編碼類:LinkedList。沒有必要編寫不同的類,因爲LinkedList是通用的並且接受LinkedList<T>

另一個例子:我們想要編碼一個AnimalList,但用戶應該有可能將AnimalList限制爲修復Animal,如Dog。這樣他就可以使用不接受CatsAnimalList
我們通過編碼類這樣做:public class AnimalList<T extends Animal> extends LinkedList<T>

// Only dogs can be added 
AnimalList<Dog> dogList = new AnimalList<Dog>(); 

// Not possible as String does not extend from Animal 
AnimalList<String> strangeList = new AnimalList<String>(); 

順便說一句,類AnimalList我們的元素是從T型內。由於T extends Animal,這樣的對象使我們能夠訪問來自Animal的每個方法。例如,AnimalList可以像isEveryoneAlive()的方法,它可能是這樣的:

public boolean isEveryoneAlive() { 
    for (T animal : getAllElements()) { 
     if (!animal.isAlive()) { 
      return false; 
     } 
    } 
    return true; 
} 

你看,animalT型,從Animal延伸。因此我們可以使用方法Animal#isAlive

相關問題