专业的JAVA编程教程与资源

网站首页 > java教程 正文

java泛型上下边界(? extend T,?super T)

temp10 2025-03-25 17:24:11 java教程 7 ℃ 0 评论

以下案例基于此代码:

class Animal{  }

/************ 鸟类  ************/
class Bird extends Animal{  }
// 乌鸦
class CrowBird extends Bird{  }
// 喜鹊
class MagpiedBird extends Bird{  }

/************ 犬类****** ******/
class Dog extends Animal{  }
// 牧羊犬
class ShepherdDog extends Dog{  }
// 二哈
class ErhaDog extends Dog{  }

/********* 鱼类 *********/
class Fish extends Animal{  }
// 金鱼
class GlodFish extends Fish{  }
// 鲨鱼
class SharkFish extends Fish{  }


java泛型上下边界(? extend T,?super T)

一、抛出问题:

1、List与List,List的区别?

2、为啥List不能add非空对象,只能get?List可以add,但是get出来的为Object?

先看java中泛型的几个基本问题:

a、List birdList = new ArrayList<>();等价于List birdList = new ArrayList()。

结论:实例化时不写泛型,默认和声明时泛型一致;实例化时的泛型与声明时的泛型要一致,否则会报错。

b、List birdList = new ArrayList<>(); birdList中可以添加Bird及Bird的所有子类。

结论:集合中只能添加指定的泛型类型及其子类型。

c、List与List不是继承关系,这是引入List的原因。

一、泛型上边界

?extend Bird表示泛型上边界。举例,List表示实例化的对象的泛型只能是Bird及其子类。有如下特点:

1、不能向集合中添加非空元素;

2、只能从集合中获取元素;

千万注意,List birdList,不是表示birdList中能添加Bird及Bird的子类,那是List的功能。List birdList表示birdList可以实例化成new ArrayList(),new ArrayList(),new ArrayList()。即birdList最终实例化的集合的泛型是Bird或者Bird的子类。


二、泛型下边界

?super Bird表示泛型下边界。举例,List表示实例化的对象的泛型只能是Bird及其父类。有如下特点:

1、能向集合中添加元素;只能添加super后面指定泛型类型及其子类型元素。

2、能从集合中获取元素,但是Object类型。

千万注意,List birdList,不是表示birdList中能添加Bird及Bird的父类。List birdList表示birdList可以实例化成new ArrayList(),new ArrayList()。即birdList最终实例化的集合的泛型是Bird或者Bird的父类。

三、深入理解

通过下面的例子和图形来回答上面抛出的问题

泛型上边界代码分析入下:

package com.stone.gen;

import java.util.ArrayList;
import java.util.List;

public class GenericParadigm {
	public static void main(String[] args) {
		List birdList = null;
		// is ok;此时存储的数据只能是Bird及子类
		birdList = new ArrayList();

		// is ok;此时存储的数据只能是CrowBird及子类
		birdList = new ArrayList();

		// is ok;此时存储的数据只能是MagpiedBird及子类
		birdList = new ArrayList();

		// is error;声明与实例化冲突了,IDE报错
		birdList = new ArrayList();
		/*
		 * 也就是说,List birdList表示具体实例化的对象的泛型必须是Bird或者Bird的子。
		 * 所以这儿的list到底是什么类型的泛型,取决于最终的实例化。 List birdList可能是new
		 * ArrayList(),这个时候只能添加Bird及子类 List birdList可能是new
		 * ArrayList(),这个时候只能添加CrowBird及子类 List
		 * birdList可能是new ArrayList(),这个时候只能添加MagpiedBird及子类
		 * 所以,List birdList中不能添加。因为具体的泛型对象不确定。但是可以get,因为
		 * Bird是泛型的上限,从里面取出来得对象,必定是Bird对象。
		 */
	}
}

class Animal {}

/*** 鸟类 ***/
class Bird extends Animal {}
// 乌鸦
class CrowBird extends Bird {}
// 喜鹊
class MagpiedBird extends Bird {}

/*** 犬类 ***/
class Dog extends Animal {}
// 牧羊犬
class ShepherdDog extends Dog {}
// 二哈
class ErhaDog extends Dog {}

/*** 鱼类 ***/
class Fish extends Animal {}
// 金鱼
class GlodFish extends Fish {}
// 鲨鱼
class SharkFish extends Fish {}

原因分析:

new ArrayList里存储的只能是Bird及其子类;

new ArrayList里存储的只能是CrowBird及其子类;

new ArrayList里存储的只能是MagpedBird及其子类;

1、那如果按照List birdList中存储的是Bird及其子类这

种方式理解的话,那我们把birdList实例化成new ArrayList(),

这样是不是就不能放Bird了,只能放CrowBird及其子类了,推翻了我们

的错误理解。这就是上边界不能add的原因。

2、由于是上边界,就是存储的对象类型的上限,所以里面存储的一定是Bird

及其子类型,所以取出来一定是Bird。所以能get。

3、根本原因是List不是实例化的对象的子集。

泛型下边界分析如下:

package com.stone.gen;

import java.util.ArrayList;
import java.util.List;

public class GenericParadigm {
	public static void main(String[] args) {
		List birdList = null;
		birdList = new ArrayList();// is ok;此时存储的数据只能是Bird及子类
		birdList = new ArrayList();// is ok;此时存储的数据只能是Animal及子类
		birdList = new ArrayList();// is error;声明与实例化不一致,IDE报错
		/*
		 * 也就是说,List list表示具体实例化的对象的泛型必须是Bird或者Bird的父。 List list可能是new ArrayList(),这个时候只能添加Bird及其子 List list可能是new ArrayList(),这个时候只能添加Animal及其子
		 */
	}
}

class Animal {}

/*** 鸟类 ***/
class Bird extends Animal {}
// 乌鸦
class CrowBird extends Bird {}
// 喜鹊
class MagpiedBird extends Bird {}

/*** 犬类 ***/
class Dog extends Animal {}
// 牧羊犬
class ShepherdDog extends Dog {}
// 二哈
class ErhaDog extends Dog {}

/*** 鱼类 ***/
class Fish extends Animal {}
// 金鱼
class GlodFish extends Fish {}
// 鲨鱼
class SharkFish extends Fish {}

原因分析:

List birdList = null;我们在实例化时,实例化对象的泛型

对象是Bird或者Bird的父,即:

birdList = new ArrayList();

birdList = new ArrayList();

1、Bird是下限,new ArrayList();可以存储Bird及其子;

new ArrayList();可以存储Animal及其子,是不是包含了Bird

及其子。所以集合里面可以添加Bird及其子。这就是下边界为什么可以

add的原因,因为实例化出来的集合对象一定包含了下限。所以,

下边界描述的是能能add(super后面指定泛型类型及其子类型)元素。

2、但是获取出来的对象可能是Bird,也可能是Animal,不知道具体类型,

所有get出来是Object。

3、根本原因是List是实例化的对象的子集。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表