public static <T> void copy1(List<? extends T> src, List<? super T> dest) {
for (int i = 0; i < src.size(); i++) {
dest.add(src.get(i));
}
}
public static <T> void copy2(List<? extends T> src, List<T> dest) {
for (int i = 0; i < src.size(); i++) {
dest.add(src.get(i));
}
}top 2方法都能实现PECS效果,但有什么区别??
谢谢你!!
发布于 2020-03-12 13:31:17
PECS -> Producer扩展了消费者超级
class A{
public int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
class B extends A
{
public int b;
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
public class GenericsDemo {
public static void main(String[] args) {
List<A> invariant = new ArrayList<>();
List<? extends A> covariant = new ArrayList<>();
List<? super A> contravariant = new ArrayList<>();
invariant.add(new B());
invariant.get(0).getA();
//Error as it expect the instance of A while reading
// invariant.get(0).getB();
//Error it will be used to read the values, we can't insert any values in it.
// We will use this construct places like defining params to a function
//covariant.add(new B());
//covariant.add(new A());
contravariant.add(new A());
contravariant.add(new B());
//Error, it will be used to write only
//While reading, it will give you object type
//contravariant.get(0).getA();
//We can type-cast while reading
A a = (A) contravariant.get(0);
a.getA();
copy1(invariant,invariant);
copy2(invariant,invariant);
//Error due to the dest param requires super of T
// copy1(covariant,covariant);
//Error due to the dest param requires of T
//copy2(covariant,covariant);
copy1(covariant,contravariant);
copy2(covariant,contravariant);
}
public static <T> void copy1(List<? extends T> src, List<? super T> dest) {
for (int i = 0; i < src.size(); i++) {
dest.add(src.get(i));
}
}
public static <T> void copy2(List<? extends T> src, List<T> dest) {
for (int i = 0; i < src.size(); i++) {
dest.add(src.get(i));
}
}
}- Methpd 2---> public static void copy2(List src, List dest) dest list will consume anything with type T and it's sub class. But, when we read it, it will return the instance of T
参考--> https://medium.com/@isuru89/java-producer-extends-consumer-super-9fbb0e7dd268
PS:-很抱歉回答得太长了。
发布于 2020-03-12 13:48:08
在这个特定的示例中,两种方法都是相同的,因为类型T本身是无界的。因此,这两个声明都只是说明dst参数列表元素必须是src参数列表元素的超类,在copy1()中使用? super T并不会在这里添加任何新内容。
super规则并不意味着你必须总是把extends或PECS放在任何地方。下面是J.Bloch "Effective Java“的第32项中与PECS兼容的声明的完整示例:
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2);这里不需要使用返回类型作为Set<? super E>。
https://stackoverflow.com/questions/60647745
复制相似问题