<T>
與<T extends Object
完全相同。所以T
可以是從Object
延伸的任何東西,這是Java
中的每個類。例如,您可以編寫<T extends Animal>
,然後您可以將從Animal
延伸的所有內容(如Cat
或Dog
)。重要的是,在該方法中,您只知道它是某種類型的Animal
。因此,即使您爲該方法提供了Dog
類型的對象,您也不會有Cat
或Dog
特定方法。您只能使用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。
好的,泛型有什麼好處?您可以限制對象只能使用修復類型T
。 T
可以是任意的,但一旦選擇就會修復。
看一看Javas List
class。在仿製藥之前,您可以將任何東西放在List
之內,如Cats
和Dogs
。你將不得不編碼一個特殊的DogList implements List
類,以便只允許Dogs
爲Lists
。現在您可以編碼一個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
。這樣他就可以使用不接受Cats
的AnimalList
。
我們通過編碼類這樣做: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;
}
你看,animal
是T
型,從Animal
延伸。因此我們可以使用方法Animal#isAlive
。
你爲什麼期望他們的行爲有所不同?在這兩種情況下,你都要在列表中調用toString。在c中,你將它稱爲T類型的對象,這恰好是一個列表。在d中,你將它作爲List傳入列表中。 –
這個例子的問題是它實際上並不需要泛型(你可以簡單地使參數類型爲Object),所以很難看出它們爲什麼不同。儘管試圖將不是'List'的東西傳遞給'd',但這不起作用,但它對'c'起作用。 –
嗨,謝謝,有沒有辦法告訴我這些論據本身是不同的? –