首页 > 代码库 > Java学习笔记——泛型

Java学习笔记——泛型

如果T既要继承类又要指定接口,使用下面方式:

public class some<T extends Iterable<T> & Comparable<T>>{}

Java的泛型不具有共变性(如果B是A的子类,而Node<B>可视为一种Node<A>,则称Node具有共变性),不过可以使用类型通配字符?与extends来声明变量,使达到类似的共变性。

Node<Apple> apple = new Node<>(new Apple(), null);
Node<? extends Fruit> fruit = apple;  // 类似共变性效果;如果是Node<Fruit> fruit = apple; 则会编译错误

若声明?不搭配extends,则默认为? extends Object,如:

Node<?> fruit = null;  // 相当于<span style="font-family: Arial, Helvetica, sans-serif;">Node<? extends Object></span>

注意:这与声明Node<Object>不同,如果是声明为Node<Object>,则只能参考至Node<Object>实例,下面的程序编译会出错:

Node<Object> node = new Node<Integer>(1, null);  // 没有共变性

应该是:

Node<?> node = new Node<Integer>(1, null);


一旦使用?与extends限制了T的类型,就只能通过T声明的名称取得对象指定给Object,或将T声明的名称指定为null,除此之外,不能进行其他指定动作

Node<? extends Fruit> fruit = new Node<>(new Apple(), null);
Object o = node.value;
node.value = http://www.mamicode.com/null;>

以上程序,只知道value参考的对象类型会是继承Fruit,但实际上会是Apple还是Banana?如果实际上node.value是Banana的实例,那指定给Apple类型的apple就是不对的


另:

Java的泛型语法只在编译时检查,执行时类型中未知的,执行时期实际上只会知道是Object类型(又称为“类型抹除”),如:

List<Integer> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
System.out.println(list1.equals(list2));  // 输出true














Java学习笔记——泛型