Java范型从范围上分,有范型类和范型方法两种,这里只讨论范型方法,从语义上来说,范型中的 T 和 ? 都有“任意一个类”(或者“任意一种类型”)的意思,那么二者的区别是什么呢?我认为是 T 可以放在Field或者Method名称前作为类型名,而 ? 不行,除此之外本质上完全一样,下面的代码是一个实例。
package org.leechau.genericEx;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
public class GenericTest {
private final ArrayList
private final ArrayList
public
return pa.get(0).toString();
}
public String mb(ArrayList <?> pa) {
return pa.get(0).toString();
}
@Before
public void setUp() throws Exception {
p1.add("1st strings");
p2.add(51);
}
@Test
public void testMa() {
System.out.println(ma(p1));
System.out.println(ma(p2));
}
@Test
public void testMb() {
System.out.println(mb(p1));
System.out.println(mb(p2));
}
}
下面的代码演示了如何分别用 T 和 ? 完成相同的实现。
T版:
package org.leechau.genericEx;
import java.util.Collection;
public abstract class Animal {
public
}
package org.leechau.genericEx;
import java.util.ArrayList;
import java.util.Collection;
public class Dog extends Animal {
@Override
public
System.out.println(this.toString() + " play with "
- playGroup.toString());
}
public static void main(String[] args) {
Collection
Dog aDog = new Dog();
aDog.playWith(dogs);
}
}
?版:
package org.leechau.genericEx;
import java.util.Collection;
public class Animal2 {
public void playWith(Collection <? extends Animal2> playGroup) {}
}
package org.leechau.genericEx;
import java.util.ArrayList;
import java.util.Collection;
public class Dog2 extends Animal2 {
@Override
public void playWith(Collection<? extends Animal2> playGroup) {
System.out.println(this.toString() + " play with "
- playGroup.toString());
}
public static void main(String[] args) {
Collection
Dog2 aDog = new Dog2();
aDog.playWith(dogs);
}
}
Java的范型(尤其是实现机制)给我的感觉是不够优雅,当一堆<>嵌套在一起的时候让人觉得像天书一样,背离了Java简洁易用的原则,但即便如此,毕竟现在Java还是产品开发(尤其是大规模产品)的主流工具,我们有必要理解它的一些细节。[1]的Part I,II 和[2]的第12章对范型的讲解比较透彻,[3]的4.3.7节则对Java范型进行了中肯的评价, [1]的Part III探讨了如何将没有范型的老代码改为有范型的新代码以保证类型安全 。
[1] Venkat Subramaniam, Generics in Java
[2] Cay S. Horstmann, Core Java. Volume I, Fundamentals, 8th ed, 2007.9
[3] Bruce A. Tate, Beyond Java, 2005.9