java泛型中,上下界通配符(跟)

背景介绍:java中的泛型,是在java5.0后才引用的,泛型,可让咱们更安全的操做容器,而不用担忧出现让人很是不快的ClassCastException异常,可是泛型没有多态的概念,Sun的那群大脑壳,就想到了一个解决办法,就是上界通配符<? extends T>,跟下界通配符(<? super T>),下面就介绍一下我的对它的理解吧,

 

首先,咱们先定义几个类:java

Leve2

class Food{}

Leve2

class Fruit{}
class Meat{}

Leve3

class Apple{}
class WaterMelon{}

 

继承关系图以下:安全

 

而后咱们定义2个不使用通配符的方法:app

/**
	 * 不使用上界通配符
	 */
	public static void isUpMethod(List<Fruit> list){

	}


	/**
	 * 不使用下界通配符
	 */
	public static void isDownMethod(List<Fruit> list){

	}

 

接着,咱们使用2个List,放函数里面存参数:函数

List<Apple> apples = new ArrayList<>();

		apples.add(new Apple());
		apples.add(new Apple());
		apples.add(new Apple());

		//两个方法编译会报错
		//isUpMethod(apples);
		//isDownMethod(apples);

		List<Fruit> fruits = new ArrayList<>();

		fruits.add(new Fruit());
		fruits.add(new Fruit());
		fruits.add(new Fruit());

		//编译经过
		isUpMethod(fruits);
		isDownMethod(fruits);

有同窗就会问了,List的泛型指定了Fruit类型,另一个List泛型指定了Apple确定编译不过去啊,可是,别忘了,Apple是Fruit的子类,咱们理解中 Fruit fruit = new Apple();是可行的,由于java的多态;

可是,泛型是没有多态的,它可不认为Apple是Fruit的子类,若是这样的话,为代码重用代码很大的麻烦,由于泛型只是编译级别,在运行期间,泛型是会擦除的;

PS:指定泛型集合后,往内添加的元素能够是Fruit的子类,由于会自动向上转型,触发多态

若是想isUpdownMethod或者isDownMethod函数,接收其泛型类的子类或者父类,这时候,咱们就可使用上界通配符了<? extends Fruit>跟下界通配符<? super Fruit>

 

咱们定义一个以下函数:ui

/**
	 * 上界通配符
	 */
	public static void upMethod(List<? extends Fruit> list){
		//编译报错
		//使用通配符后,不能在往集合类中添加元素
		//list.add();


		//使用通配符后,是能够取出元素的
		//全部取出的元素,都是上界父类元素
		Fruit fruit = list.get(0);
	}


	/**
	 * 下界通配符
	 */
	public static void downMethod(List<? super Fruit> list){
		//下界通配符能够往容器内添加元素
		//可是有限制,必须是Fruit的子类或者自己,父类是添加不进去的
		list.add(new Apple());

		//取出元素的类型都为Object
		Object object = list.get(0);
	}

而后,咱们试试使用往函数类传输LIST集合泛型指定是子类的集合:spa

List<Apple> apples = new ArrayList<>();

		apples.add(new Apple());
		apples.add(new Apple());
		apples.add(new Apple());


		List<Fruit> fruits = new ArrayList<>();

		fruits.add(new Fruit());
		fruits.add(new Fruit());
		fruits.add(new Fruit());

		List<Food> foods = new ArrayList<>();

		foods.add(new Food());
		foods.add(new Food());
		foods.add(new Food());
		
		//编译经过
		upMethod(apples);
		upMethod(fruits);
		
		//编译经过
		downMethod(fruits);
		downMethod(foods);

 

 

上界通配符<? extends Fruit>

简介:code

  •     上界通配符中的上界,指的是泛型内的类型,最高是Fruit类,最低不限,只要是继承了Fruit类,均可以经过编译,这也就是为何叫 "上界",最高类型就是Fruit类          

描述:

  • 在upMethod函数中,使用上界通配符后,限定了条件,传参对象的泛型,必须是Fruit类或者其子类,才能经过编译,不然,编译就会失败,

  • 特性:
    • 在使用上界通配符后,咱们不能在往集合内添加元素,那是由于,虽然指定了泛型的类型是Fruit类或者其子类,可是Fruit类可能并不止一个子类,可能除了Apple外还有Banana或者Watermelon类,若是你传递进来的是Apple集合,可是往里面添加Banana,这种状况下,往外取元素的时候很大的可能性会出现异常,由于取出的元素不是Apple而是Banana.因此,避免出现这种状况,使用上界通配符后,是不能再往集合内添加元素,
    • 能够往外取元素,全部取出的元素都是Fruit类,由于,编译器只知道是Fruit的子类,可是殊不知道是具体哪一个子类,因此取出的元素是最高层的类,也就是Fruit类

 

 

---------------------------------分割线----------------------------------------对象

 

 

下界通配符<? super Fruit>描述:

简介:继承

  •     下界通配符中的下界,指的是泛型内的类型,最低是Fruit类,最高到超类Object,只要是Fruit的父类,均可以经过编译,这也就是为何叫 "下界",由于最低是Fruit类       

描述:

  • 在downMethod函数中,使用下界通配符后,限定了条件,传参对象的泛型,必须是Fruit类或者其父类,才能经过编译,不然,编译就会失败,

  • 特性:
    • 能够往集合内添加元素,可是限制条件是往内添加的元素,必须是Fruit的子类,由于虽然知道是Fruit的基类 但也不知道是往上数多少级的基类 只有Fruit以及它的子类 编译器才能判定能触发多态,
    • 能够往外取元素,可是取出来的元素都是Object,由于取出来的有多是Food,比Fruit范围大,不能赋值给Fruit对象。只有Object能够,由于没有类比Object大。

 

 

---------------------------------分割线----------------------------------------内存

有人可能会问,为何使用上界通配符后,不能往里存元素了,可是使用下界通配符能往里面存元素,缘由以下:

  1. 上界通配符指定了上限,最高就是Fruit类,往里存元素,不是Fruit就是其子类啊,理论上是能够往内存的,那是由于使用上界通配符后,虽然有上限,可是没有下限啊,编译器,只知道是Fruit类或者是Fruit的子类,可是具体是哪一个类型的子类,编译器也不知道,为了防止出现类型转换错误,因此,就禁止再往内添加元素(若是是我,我也会这么作,避免出现这样的状况)

  2. 下界通配符能往内存元素是由于下界通配符,规定了最小粒度的下限,是Fruit类.其实是放松了对元素的类型控制,既然元素是Fruit类的父类,那往里存Fruit子类确定能够的,由于Fruit的子类,也是其Fruit父类的子类,

  3. 上界通配符<? extends Fruit> 能够当作<?> 类型都不知道,确定不让往里面添加元素,由于没有下限;也能够当作是一个能够放某种Fruit的集合,不是一个能够听任何Fruit的大杂烩集合
  4. 下界通配符<? super Fruit> 能够当作<Fruit>,肯定了类型最低是Fruit,因此能够往内添加元素,可是必须是Fruit或者其子类​​​​​​​;也能够当作是一个能够听任何Fruit的集合

 

---------------------------------分割线----------------------------------------

 

总结:

  •         上界通配符<? extends T> 指的是,引用内的泛型范围,最高是T类,最低不限
    • 能够取元素
    • 不能添加元素
  •         下界通配符<? super T> 指的是,引用内的泛型范围,最低是T类,最高是超类Object
    • 能够取元素,可是取出的元素是Object
    • 能够添加元素,添加的元素,必须是T类或者其子类

 

到这,文章就结束了!

以上,均为本人理解,若是理解错误,欢迎指正

欢迎转载,请注明出处跟做者,谢谢!

相关文章
相关标签/搜索