我真的很抱歉,因为我认为我理解通用但我没有,对我感到羞耻。
这两者之间有什么区别
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表示参数类型或类/对象?
答案 0 :(得分:2)
如果是c
,您的T
可以是任何内容,其中包含一个列表。但是因为Java不知道它是什么,所以你不能对它进行任何特定于列表的操作。
如果是d
,则您的T
必须是列表。因为Java知道它是什么,所以你可以做一些事情,比如添加,删除和迭代等等。
答案 1 :(得分:1)
<T>
与<T extends Object
相同。因此,T
可以是Object
延伸的任何内容,Java
中的每个类都是<T extends Animal>
。例如,您可以撰写Animal
,然后您可以将所有内容都放在Cat
之内,例如Dog
或Animal
。重要的是,在方法中你只知道它是某种类型的Cat
。因此,即使您为方法指定了Dog
类型的对象,您也不会拥有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
在你的例子中也是如此。方法T
接受从Object
延伸的任何Java
,因此d
中的每个对象都是如此。方法List<T>
接受List
类型的对象。这些是T
个对象,只包含T
类型的元素。在这种情况下,T extends Object
再次表示d
。因此List
接受包含Object
s的<{1}}。
好的,仿制药有什么好处?您可以将对象限制为仅使用修复类型T
。 T
可以是任意的,但一旦选择就可以修复
看看Javas List
课程。在泛型之前,您可以在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
。这样他就可以使用不接受AnimalList
的{{1}}
我们通过对类进行编码来实现:Cats
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
。