What's the purpose behind wildcards and how are they different from generics?
几天前我从未听说过野车,在看过我老师的JAVA书后,我仍然不知道它是什么,为什么我需要使用它。
比如说,我有一个超类
1 | List<Animal> listAnimals |
相反,我的同事推荐的是:
1 | List<? extends Animal> listAnimals |
为什么我应该使用通配符而不是简单的泛型?
假设我需要一个get/set方法,我应该使用前者还是后者?它们有什么不同?
当您声明局部变量时,通配符没有多大意义,但是当您声明方法的参数时,通配符确实很重要。
假设你有一个方法:
1 2 3 4 5 6 7 8 9 10 | int countLegs ( List< ? extends Animal > animals ) { int retVal = 0; for ( Animal cur : animals ) { retVal += cur.countLegs( ); } return retVal; } |
有了这个签名,你就可以做到:
1 2 3 4 5 6 7 8 | List<Dog> dogs = ...; countLegs( dogs ); List<Cat> cats = ...; countLegs( cats ); List<Animal> zoo = ...; countLegs( zoo ); |
但是,如果您声明如下:
1 | int countLegs ( List< Animal > animals ) |
然后在前面的示例中,只有
Java泛型是不变量的。
假设我们有
B 是A 的一个亚型。instanceof B 也是instanceof A 。
因为Java数组是协变的:
B[] 是A[] 的一个亚型。instanceof B[] 也是instanceof A[] 。
然而,Java泛型是不变量的:
通配符用于使其更灵活,同时保持类型安全。
List 是List extends A> 。
工具书类
- Java教程/泛型
- 子类型
- 野猫游戏更有趣
相关问题
- 有什么简单的方法来解释为什么我不能做
List ?animals = new ArrayList () - Java泛型(非)协方差
和 有什么区别?
你的两个例子之间的区别仅仅是第一个例子是一个普通/普通动物的列表-因此你可以在其中添加任何类型的动物,以及任何类型动物的子类实例。(例如,它可以包含一些狗,一些猫,一些豪猪…)而第二个-
你可以把狗和猫放在一个
假设您有一种方法,可以获取动物列表:
1 2 3 | void foo(List<Animal> animals) { ... } |
现在您不能将方法传递给一个狗列表——它只需要一个类型为
1 2 3 | void foo(List<? extends Animal> animals) { ... } |
见
http://java.sun.com/docs/books/tutorial/extra/generics/通配符.html