[学习总结]Java泛型的几点补充

Java 泛型中 ? 通配符的理解

通配符 跟泛型参数有相同的思想. 可是在细节上却又并不相同. 

先看看通配符能怎么用吧. 下面这段话摘自 Sun公司的高级Java开发人员 Brian Goetz对通配符的解释

对泛型类 ArrayList 而言,对于任意(引用)类型 TArrayList<?> 类型是 ArrayList<T> 的超类型(类似原始类型 ArrayList 和根类型 Object,但是这些超类型在执行类型推断方面不是很有用)。

通配符类型 List<?> 与原始类型 List 和具体类型 List<Object> 都不相同。如果说变量 x 具有 List<?> 类型,这表示存在一些 T 类型,其中 x 是 List<T>类型,x 具有相同的结构,尽管我们不知道其元素的具体类型。这并不表示它可以具有任意内容,而是指我们并不了解内容的类型限制是什么 — 但我们知道存在某种限制。

对于这段话中说的 "ArrayList<?> 是 ArrayList<T> 的超类型", 从下面的解释中很容易理解到, 如果一个方法, 或者引用类型中使用了 <?> 那么代表它引用的对象对于类型是有限制的. 可是在定义变量时不会管它的限制类型是什么.

看看下面这段代码:

		HashSet<String> collection1 = new HashSet<Integer>(); //报错
		HashSet<?> collection2 = new HashSet<Integer>();
		collection2 = new HashSet<String>(); 
代码中第1和第3行都会在编译器中出现错误提示. 

  • 第1行是因为引用变量 collection1 已经被指定了具体的类型参数String, 可指向的对象中却是Integer.
  • 第2行中, 通过用通配符确定了collection2 具有某种类型限制, 可是具体是什么限制在定义collection2的时候没有说明. 所以指向HashSet<Integer>这个对象自然也没问题.
  • 第3行中, collection2虽然在第2行指向了具有具体参数类型的对象, 可由于collection2本身是被 HashSet<?> 所定义的, 因此在以后还可以指向具有不同的参数类型的对象.
		HashSet<String> collection3 = new HashSet<String>();
		collection3 = new HashSet<Integer>(); //报错
这两行代码说明了, 第一个例子里面第3行那种情况对于在定义时已经确定了参数类型的对象是不可行的.

通配符与 extends/super 边界限定符的搭配

边界限定符很容易理解, 这里就简单说说.
通过情况下, 通配符都会跟上面这两个边界限定符的其中一个或多个搭配使用来确定自己能接受类型的范围. 如果不搭配边界限定符的话, 上面例子中完全不使用通配符, 只用原始类型来定义引用变量效果是一样的. 而通配符中所说的对于类型是有限制的其限制方法就是使用边界限定符: 1) ? extends Type 代表通配符只能接受的Type和其下面的类型. 2) ? super Type 代表通配符只能接受的Type和其上面的类型.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值