以下案例基于此代码:
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{ }
一、抛出问题:
1、List
2、为啥List extends bird>不能add非空对象,只能get?List super bird>可以add,但是get出来的为Object?
先看java中泛型的几个基本问题:
a、List
结论:实例化时不写泛型,默认和声明时泛型一致;实例化时的泛型与声明时的泛型要一致,否则会报错。
b、List
结论:集合中只能添加指定的泛型类型及其子类型。
c、List
一、泛型上边界
?extend Bird表示泛型上边界。举例,List extend bird>表示实例化的对象的泛型只能是Bird及其子类。有如下特点:
1、不能向集合中添加非空元素;
2、只能从集合中获取元素;
千万注意,List extend bird> birdList,不是表示birdList中能添加Bird及Bird的子类,那是List
二、泛型下边界
?super Bird表示泛型下边界。举例,List super bird>表示实例化的对象的泛型只能是Bird及其父类。有如下特点:
1、能向集合中添加元素;只能添加super后面指定泛型类型及其子类型元素。
2、能从集合中获取元素,但是Object类型。
千万注意,List super bird> birdList,不是表示birdList中能添加Bird及Bird的父类。List super bird> birdList表示birdList可以实例化成new ArrayList
三、深入理解
通过下面的例子和图形来回答上面抛出的问题
泛型上边界代码分析入下:
package com.stone.gen;
import java.util.ArrayList;
import java.util.List;
public class GenericParadigm {
public static void main(String[] args) {
List extends bird> 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 extends bird> birdList表示具体实例化的对象的泛型必须是Bird或者Bird的子。
* 所以这儿的list到底是什么类型的泛型,取决于最终的实例化。 List extends bird> birdList可能是new
* ArrayList(),这个时候只能添加Bird及子类 List extends bird> birdList可能是new
* ArrayList(),这个时候只能添加CrowBird及子类 List extends bird>
* birdList可能是new ArrayList(),这个时候只能添加MagpiedBird及子类
* 所以,List extends bird> 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
new ArrayList
new ArrayList
1、那如果按照List extends bird> birdList中存储的是Bird及其子类这
种方式理解的话,那我们把birdList实例化成new ArrayList
这样是不是就不能放Bird了,只能放CrowBird及其子类了,推翻了我们
的错误理解。这就是上边界不能add的原因。
2、由于是上边界,就是存储的对象类型的上限,所以里面存储的一定是Bird
及其子类型,所以取出来一定是Bird。所以能get。
3、根本原因是List extend bird>不是实例化的对象的子集。
泛型下边界分析如下:
package com.stone.gen;
import java.util.ArrayList;
import java.util.List;
public class GenericParadigm {
public static void main(String[] args) {
List super bird> birdList = null;
birdList = new ArrayList();// is ok;此时存储的数据只能是Bird及子类
birdList = new ArrayList();// is ok;此时存储的数据只能是Animal及子类
birdList = new ArrayList();// is error;声明与实例化不一致,IDE报错
/*
* 也就是说,List super bird> list表示具体实例化的对象的泛型必须是Bird或者Bird的父。 List super bird> list可能是new ArrayList(),这个时候只能添加Bird及其子 List super bird> 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 super bird> birdList = null;我们在实例化时,实例化对象的泛型
对象是Bird或者Bird的父,即:
birdList = new ArrayList
birdList = new ArrayList
1、Bird是下限,new ArrayList
new ArrayList
及其子。所以集合里面可以添加Bird及其子。这就是下边界为什么可以
add的原因,因为实例化出来的集合对象一定包含了下限。所以,
下边界描述的是能能add(super后面指定泛型类型及其子类型)元素。
2、但是获取出来的对象可能是Bird,也可能是Animal,不知道具体类型,
所有get出来是Object。
3、根本原因是List super bird>是实例化的对象的子集。
本文暂时没有评论,来添加一个吧(●'◡'●)