论坛首页 Java企业应用论坛

【解惑】JVM如何理解Java泛型类

浏览 17848 次
该帖已经被评为精华帖
作者 正文
   发表时间:2009-12-17  
不错,挺详细的 .!
0 请登录后投票
   发表时间:2009-12-17  
Heart.X.Raid 写道

 

3、泛型约束和局限性—— 类型擦除所带来的麻烦

(1)  继承泛型类型的多态麻烦。(—— 子类没有覆盖住父类的方法 )

     

 

   ..................

     编译器 会自动在 SonPair中生成一个桥方法(bridge method )
           public void setSecond(Object sec){
                   setSecond((String) sec)
            }
      

 

 

    红色部分的方法应该是setFirst吧?

 

    呵呵,总体写的挺好的!

0 请登录后投票
   发表时间:2009-12-17   最后修改:2009-12-17
不是很明白 。按楼主的说法。如果
类Text
a,b 都继承Text
LIST<Text> text;
text.ADD(a);
text.ADD(b);

这个时候jvm怎么处理我这个泛型

0 请登录后投票
   发表时间:2009-12-17  
都擦除了,没什么额外处理
0 请登录后投票
   发表时间: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)具有相同的擦除,但是未覆盖它
0 请登录后投票
   发表时间:2009-12-17  
eroscxl 写道
不是很明白 。按楼主的说法。如果
类Text
a,b 都继承Text
LIST<Text> text;
text.ADD(a);
text.ADD(b);

这个时候jvm怎么处理我这个泛型


将a,b都向上转型成Text
0 请登录后投票
   发表时间: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)方法是一样的,没有进行重写呀
还有其它玄机吗?
2 请登录后投票
   发表时间:2009-12-17   最后修改:2009-12-17
例子都试过了,确实是这样,受益了。


0 请登录后投票
   发表时间: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的意思是 既然一样了不就能当成重写了嘛, 干嘛还报错
0 请登录后投票
   发表时间: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使用的环境一般无法确定比较的对象的类型
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics