java泛型理解
来源:互联网 发布:qt模型视图知乎 编辑:程序博客网 时间:2024/06/13 13:36
1,List
2,List<Object>
3,List<Number>
4,List<?>
5,List<? extends Number>
6,List<? super Long>
普通的泛型使用估计没啥问题,但是带上 ? 的泛型就会变得很复杂。
对于 <? super T> 和 <? extends T> 看看这个例子:
如果要将某一个数组中的元素拷贝至另一个的话
1,先看看这个方法签名:
public
static
<T>
void
copy(List<T> src, List<T> dest)
如果 src 和 dest 是相同泛型参数的话,这个签名是没有问题,但是由于泛型类与数组不一样,由于泛型类并不具有协变性,也就是说下面的代码是错误的:
List<Object> objs =
new
ArrayList<Long>();
数组是协变性的,下面的代码是正确的:
Object[] objs =
new
Long[
4
];
用这个 copy 方法的话,如果 src 是 List<Long>,而 dest 是 List<Object> 的话,这样就会产生编译错误。但是实际上 List<Long> 中的每一个元素是可以赋值给 List<Object> 的,因此这个 copy 方法签名还有待完善。
由于泛型类不具有协变性,但是 Java 的泛型提供了一个通配符类型 ? 使用这个可以将泛型类变成协变的,下面的代码是正确的:
List<?
extends
Object> objs =
new
ArrayList<Long>();
<? extends Object> 表示泛型是 Object 或者是 Object 的子类型,同理
<? super Long> 表示泛型是 Long 或者是 Long 的父类型。
这样就可以把 copy 方法完善成为:
public
static
<T>
void
copy (List<?
extends
T> src, List<?
super
T> dest)
至于其他的,看看下面的语句哪些正确的,哪些是不正确的?
Pair 是个泛型类,SubTypeOfPair 是 Pair 的子类
Collection<Pair<String, Long>> c1 =
new
ArrayList<Pair<String, Long>>();
Collection<Pair<String, Long>> c2 = c1;
// s1
Collection<Pair<String, ?>> c3 = c1;
// s2
Collection<?
extends
Pair<String, ?>> c4 = c1;
// s3
Collection<SubTypeOfPair<String, Long>> c1 =
new
ArrayList<SubTypeOfPair<String, Long>>();
Collection<Pair<String, Long>> c2 = c1;
// s4
Collection<SubTypeOfPair<String, Long>> c3 = c1;
// s5
Collection<Pair<String, ?>> c4 = c1;
// s6
Collection<?
extends
Pair<String, ?>> c5 = c1;
// s7
I will try to explain the Java generics using two simple rules. These rules suffice to answer your question and are basically enough to remember for almost any case:
- Two generic types
X<A>
andX<B>
are never assignable unlessA = B
. I.e., generics areinvariant by default. - Wildcards allow the assignment of
X<A>
:- to
X<?>
- to
X<? extends T>
iffA
is assignable toT
(apply rules recursively toA
andT
) - to
X<? super T>
iffT
is assignable toA
(apply rules recursively toT
andA
)
- to
Case c3 = c1
In your example, you try to assign Collection<Pair<String,Long>>
to Collection<Pair<String,?>>
. That is, in your case A = Pair<String,Long>
and B = Pair<String,?>
. Since these types are not equal, they are not assignable; they violate Rule 1.
The question is, why doesn't the wildcard help? The answer is simple:
Rule 2 is NOT transitive. I.e., X<X<A>>
cannot be assinged to X<X<?>>
, there has to be a wildcard in the outermost level; otherwise Rule 2 does not apply to the outermost level.
Case c4 = c1
Here, you got a wildcard in the outer type. Because it is in the outer type, Rule 2 kicks in: A = Pair<String,?>
is assignable to B = ? extends Pair<String,Long>
(again, because of Rule 2). Therefore, this is legal.
General approach
Here is how you can check any complex generic type: Simply check each generic level by level using the two rules. Start with the outermost level. Once a level violates a rules, you know the assignment is illegal; if all levels adhere to the rules, then the assignment is legal. Lets consider your types again:
X = Collection<Pair<String,Long>>Y = Collection<Pair<String,?>>Z = Collection<? extends Pair<String,?>>
Is X assignable to Y ?
// Outermost level:A = Pair<String,Long>, B = Pair<String,?> => B is no wildcard and A != B (Rule 1), so this is illegal!
Is X assignable to Z ?
// Outermost level:A = Pair<String,Long>, B = ? extends Pair<String,?> => We got a wildcard, so Rule 2 states this is legal if the inner level is legal// Inner level: (we have to check both parameters)A = String, B = String => Equal, Rule 1 applies, fine!A = Long, B = ? => B is wildcard, Rule 2 applies, fine!
Simple Rule to Remember
Each level of generic nesting either needs to be completely identical (A=B
) or B
needs to contain a wildcard in this level.
- Java泛型理解
- JAVA泛型理解
- Java 泛型理解
- Java泛型理解
- java泛型理解
- java泛型理解
- Java 泛型理解
- Java泛型理解
- Java 泛型的理解
- java泛型的理解
- java泛型理解一
- java泛型的理解
- java泛型的理解
- java中的泛型理解
- java泛型深度 理解
- JAVA中的泛型理解
- java泛型的理解
- java泛型的理解
- websphere(WAS)增量更新web.xml时的缓存问题
- 重建二叉树
- SUSE 11 sp3 下安装配置nfs共享挂载
- 指数型母函数
- play修改debug端口,同时debug多个工程
- java泛型理解
- 利用ffmpeg 推送及播放udp rtp
- Java正则表达式-使用套路
- CentOS Minimal版最小化安装后VMware联网详解
- jQuery源码阅读笔记
- 计算机端口详解
- java问题1
- 设计模式-工厂方法模式
- bootstrap弹出模态框简单例子