Java集合与泛型

在集合中使用泛型是经常见到的,之前对这一块也是懵懵懂懂,这几天研究了一下,下面总结一下:

1.List、List<T>、List<?>的区别

List与List<Object>

很多人认为List 就是List<Object>类型的集合,毕竟二者的行为绝大情况下是一样的:都可以放进去任意类型的对象,而取出来的对象都是Object类型。

List l = new ArrayList();
l.add(new Animal());
l.add(new Dog());
Object o = l.get(0);
        
List<Object> objectList = new ArrayList<>();
objectList.add(new Animal());
objectList.add(new Dog());
Object o1 = objectList.get(0);

但是二者的行为还是有所不同的。

List表示没有泛型类型,该List可以装任何东西,它就没有涉及到泛型这个概念。List:别跟我谈什么泛型,我这里就没有这个东西。Java在没有引入泛型之前,List就是这么用的。

List<Object>就很清楚了,表示Object类型的List,它也可以装所有类型的对象,那是因为Object是Java中所有类的基类,是Java多态才导致它可以装所有类型的对象的。

所以在某些情况下二者还是会有所不一样的:

// 因为l是没有类型的,所以它可以赋值给任意类型的List引用
// 这也是一种Java引入泛型以后对之前代码的兼容
List<? extends Animal> list = l;
// 下面这个这段代码是很危险的,因为list是什么类型的对象都有的
// 并不都是Animal类型的对象,这是Java为了向下兼容导致的问题
final Animal animal = list.get(0);

// 下面这行代码会报错,因为objectList已经指明了是Object类型的List,
// 而list只能引用Animal及其子类类型的List
list = objectList; 

所以,List因为没有泛型类型,是可以赋值给任意的泛型List引用的,而List<Object>就不行。

如果T是一种具体的类型,例如List<Animal>,那么意义就更加明确了,就是该List里面装的都是Animal,不能是其他类型的对象。


List<?>

List<?> 表示一个泛型通配类型的引用,它可以引用其他任意类型泛型的List,所以它可以引用List和List<Object>。

List<?>和List<Obejct>的不同在于,List<Obejct>仅仅表示它里面的元素是Object类型的,它用于限制List内部元素的类型;而List<?>作用于List的泛型类型,不管你是什么泛型类型的List,都可以用List<?>来表示。List<?>一般作为参数来接收外部的集合,或者返回一个不知道具体泛型类型的集合。

因此List<?>可以引用List<Animal>,而List<Object>则不能,因为List<Object>和List<Animal>并不是同一个类型。

但List不能添加任何非null元素,但可以remove和clear等移除操作。这是因为List<?>肯定是某个泛型类型的List,但不知道具体是哪一个泛型类型,即List<?>中的元素都是同一个类型的,要么是Dog,要么是Cat,但不可能有些元素是Dog,有些元素是Cat。但类型擦除以后,里面的元素都是用Object来表示,就无法保证类型安全了。所以要保证其里面的元素都是同一个类型的,就要在编译器的层次上来保证,不能往List<?>里面添加元素,这样就保证了List<?>里面都是同一个类型的元素。

下面用代码了说明一下:

List<Animal> animalList = new ArrayList<>();
animalList.add(new Animal());

// List<?> 可以引用任意泛型类型的List
listAny = animalList;
// 由于类型擦除,取出来的元素都是Oject类型的。
final Object o2 = listAny.get(0);

// 可以添加null
listAny.add(null);
// 为了保证类型安全,不能添加其他元素
listAny.add(new Object());

// 报错,List<Object>和List<Animal>不是同一类型的。
objectList = animalList;

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值