java? extends E和? super E 的区别

java中<? extends E>和<? super E> 的区别


import java.util.ArrayList;

public class Do1 {
	/*
	 * Q:探究<? extends E>和<? super E>的使用和意义区别
	 * 通过预编译报错区别两者的使用区别
	 * */
	public static void main(String[] args) {
		/*
		 * <? extends person>使用时,person本身和他的子类(子类的子类)都没有报错
		 * */
		ArrayList<? extends Person> al1 = new ArrayList<Person>();
		ArrayList<? extends Person> al2 = new ArrayList<Man>();
		ArrayList<? extends Person> al3 = new ArrayList<Woman>();
		ArrayList<? extends Person> a14 = new ArrayList<ManBoy>();
		
		/*
		 * <? super person>使用时,除了person本身没有报错外,其他都报错
		 * */
		ArrayList<? super Person> b11 = new ArrayList<Person>();
		ArrayList<? super Person> b12 = new ArrayList<Man>();			//报错
		ArrayList<? super Person> b13 = new ArrayList<Woman>();			//报错
		ArrayList<? super Person> b14 = new ArrayList<ManBoy>();		//报错
		
		/*
		 * <? extends man>使用时,men本身和其子类没有报错,他的父类person和平行子类woman报错
		 * */
		ArrayList<? extends Man> cl1 = new ArrayList<Person>();			//报错
		ArrayList<? extends Man> cl2 = new ArrayList<Man>();
		ArrayList<? extends Man> cl3 = new ArrayList<Woman>();			//报错
		ArrayList<? extends Man> c12 = new ArrayList<ManBoy>();
		
		/*
		 * <? super man>使用时,man本身和父类没有报错,子类menboy和平行子类woman报错
		 * */
		ArrayList<? super Man> d11 = new ArrayList<Person>();
		ArrayList<? super Man> d12 = new ArrayList<Man>();
		ArrayList<? super Man> d13 = new ArrayList<Woman>();			//报错
		ArrayList<? super Man> d14 = new ArrayList<ManBoy>();			//报错
		
		//通过上面的例子可以判断出
		//<? extends E>为泛型固定上界,当后面的实例类型是本身和子类(子类的子类)都是不会报错的
		//<? super E>为泛型固定下界,当后面的实例类型是本身和其父类时不报错
		
		/*
		 * 证明:通过<? extends woman>本身和子类不报错
		 **/
		ArrayList<? extends Woman> el3 = new ArrayList<Woman>();
		ArrayList<? extends Woman> e12 = new ArrayList<WomanGirl>();
		
		/*
		 * 证明:通过<? super woman>本身和父类不报错
		 * */
		ArrayList<? super Woman> f13 = new ArrayList<Person>();
		ArrayList<? super Woman> f14 = new ArrayList<Woman>();
	}

}

class Person{
	
}

class Man extends Person{
	
}

class ManBoy extends Man{
	
}

class Woman extends Person{
	
}

class WomanGirl extends Woman{
	
}

在上面的例子中,创建了Person类和子类Man类、Woman类。两个子类各自又扩展了两个子类。通过实例报错验证使用方法。

具体的使用意义的差别是

  • <? extends E>   泛型固定上界接受本类和子类
  1. 在集合框架中,想要将子类集合的东西addAll()进父类集合中。父类集合名.addAll(子类集合名)
  2. 直接对父类集合经行扩容,将父类引用指向子类实例。此为父类引用指向子类的父类集合实现
  • <? super E>      泛型固定下界——接受本类和父类
  1. 可双列集合(map)中,进行比较器(Comparator)的代码重用,提高效率
  2. 比较器(Comparator)使用父类类型编写,这样子类也可以向上转型使用。此为父类引用指向子类在比较器中的实现

补充:

java中的泛型一共有是三种

  • ArrayList<T> al=new ArrayList<T>();          指定集合元素只能是T类型
  • ArrayList<?> al=new ArrayList<?>();             集合元素可以是任意类型,这种没有意义,一般是方法中,只是为了说明用法
  1. 编译1:报错:ArrayList<? extends E> al=new ArrayList<? extends E>();
  2. 编译2:报错:ArrayList<?> al=new ArrayList<?>();
  3. 编译3:成功:ArrayList<?> al=new ArrayList<String>();
  •  泛型的限定:
  1. <? extends E>:接收E类型或者E的子类型。
  2. <?super E>:   接收E类型或者E的父类型。
                   
                   

猜你喜欢

转载自blog.csdn.net/z1162565234/article/details/84033140