您的位置:首页 > 编程语言 > Java开发

浅谈java中<? super E> and <? extends E>的区别

2017-03-22 15:18 453 查看
在java的很多包源码中都能看到泛型<? super E> 和 <? extends E>,正好整理了下它们之间的区别。

1、<? super E> ? 代表该类为E类或者为E的父类;

2、<? extends E> ?代表该类为E类或者为E的子类;

这类规范一般在继承和不同集合类直接的转化时会起到作用,主要为了保证类型安全。

以java.util.concurrent.LinkedBlockingQueue;为例。

首先看下LinkedBlockingQueue的一段构造函数源码:

public LinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
final ReentrantLock putLock = this.putLock;
putLock.lock(); // Never contended, but necessary for visibility
try {
int n = 0;
for (E e : c) {
if (e == null)
throw new NullPointerException();
if (n == capacity)
throw new IllegalStateException("Queue full");
enqueue(new Node<E>(e));
++n;
}
count.set(n);
} finally {
putLock.unlock();
}
}
方法内部都不用看,只需关注入参Collection<? extends E> c,含义是用Collection作为构造函数入参时,Collection的泛型必须和LinkedBlockingQueue的泛型一样,或者是LinkedBlockingQueue泛型的子类。

定义了下面三个类,类之间关系如下:

class Grandparent{

}
class Parent extends Grandparent{

}

class Daughter extends Parent {

}有一个以Parent作为泛型的LinkedBlockingQueue类和以Daughter为泛型的List类:
LinkedBlockingQueue<Parent> linkedBlockingQueue;

List list = new LinkedList<Daughter>();

根据LinkedBlockingQueue构造函数的规范,可以用linkedBlockingQueue = new LinkedBlockingQueue<Parent>(list);的方式来初始化linkedBlockingQueue,因为Daughter为Parent的子类,可以保证所有类成员都安全拷贝,但是不能用linkedBlockingQueue
= new LinkedBlockingQueue<Parent>(new LinkedList<Grandparent>);的方式来初始化,因为可能会存在类元素与Parent不兼容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 泛型