锁定老帖子 主题:【解惑】JVM如何理解Java泛型类
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-17
不错,挺详细的 .!
|
|
返回顶楼 | |
发表时间:2009-12-17
Heart.X.Raid 写道
3、泛型约束和局限性—— 类型擦除所带来的麻烦 (1) 继承泛型类型的多态麻烦。(—— 子类没有覆盖住父类的方法 )
.................. 编译器
会自动在
SonPair中生成一个桥方法(bridge method
)
:
红色部分的方法应该是setFirst吧?
呵呵,总体写的挺好的! |
|
返回顶楼 | |
发表时间:2009-12-17
最后修改:2009-12-17
不是很明白 。按楼主的说法。如果
类Text a,b 都继承Text LIST<Text> text; text.ADD(a); text.ADD(b); 这个时候jvm怎么处理我这个泛型 |
|
返回顶楼 | |
发表时间:2009-12-17
都擦除了,没什么额外处理
|
|
返回顶楼 | |
发表时间:2009-12-17
最后修改:2009-12-17
JackAndroid 写道 haojia0716 写道 编译器就是这样说的
Name clash: The method equals(T) of type TT<T> has the same erasure as equals(Object) of type Object but does not override it 有什么看不懂的 equals(Object)和equals(T)擦除后是一样的 你自己前面也说到了 这里的T对于编译器来说就是Object 如果对编译器来说是一样,那么为什么不算是override? 不要光看提示信息,就想当然。 不能说对编译器来是完全一样, 应该说编译后是完全一样, 而编译时, 编译器会验证重写的一些判定 在这里, 编译器的工作大概有几步: 1. 编译器首先根据方法签名判断子类的equals方法是个新的方法(因为你使用的T作为参数), 与父类Object的equals方法并不产生重写关系 2. 编译器进行泛型擦除 3. 编译器发现擦除之后出现了两个完全一致的equals(Object)方法, 而子类的equal方法是擦除产生的和定义时的equals(T)对应, 这时编译器不知道你到底是想重写还是在定义一个新的equals 4. 可以预期的是, 如果编译器放过这段代码, 那么在调用equals方法时, jvm无法知道到底是在调用哪一个equals方法(因为同时存在两个equals方法, 而却不是重写关系) 所以编译器为确保代码安全, 会报错: 名称冲突:类型 Test<T> 的方法 equals(T)与类型 Object 的 equals(Object)具有相同的擦除,但是未覆盖它 |
|
返回顶楼 | |
发表时间:2009-12-17
eroscxl 写道 不是很明白 。按楼主的说法。如果
类Text a,b 都继承Text LIST<Text> text; text.ADD(a); text.ADD(b); 这个时候jvm怎么处理我这个泛型 将a,b都向上转型成Text |
|
返回顶楼 | |
发表时间:2009-12-17
【Error】 Name clash: The method equals(T) of type Pair<T> has the same erasure as equals(Object) of type Object but does not override it。
不就表示擦除后的T变成object了,和Object类的equals(Object)方法是一样的,没有进行重写呀 还有其它玄机吗? |
|
返回顶楼 | |
发表时间:2009-12-17
最后修改:2009-12-17
例子都试过了,确实是这样,受益了。
|
|
返回顶楼 | |
发表时间:2009-12-17
langyu 写道 【Error】 Name clash: The method equals(T) of type Pair<T> has the same erasure as equals(Object) of type Object but does not override it。
不就表示擦除后的T变成object了,和Object类的equals(Object)方法是一样的,没有进行重写呀 还有其它玄机吗? LZ的意思是 既然一样了不就能当成重写了嘛, 干嘛还报错 |
|
返回顶楼 | |
发表时间:2009-12-17
Kensai 写道 例子都试过了,确实是这样,受益了。
关于最后一个错误,因为equals比的是this,所以equals(Pair<T>) 就ok了。 public class Pair<T> { public boolean equals(Pair<T> value) { return (first.equals(value) && second.equals(value)); } } 当然, 这里你指定了比较的确切类型, 但是正常的equals应该覆盖Object类, 你这个写法没什么意义, 因为equals使用的环境一般无法确定比较的对象的类型 |
|
返回顶楼 | |