iteye_5049
2011-04-28 16:35
浏览 444
已采纳

泛型<T>的转换问题

问答里提问,没有得到答案,特开此贴讨论。
代码如下:


public class Cast {
public static &lt;T&gt; T cast(Object o){  
    return (T)o;  
}  

public static void main(String[] args){  
        Object o =new Bird();  
        Bird b=Cast.cast(o);  //cast方法上的Doc提示:&lt;Bird&gt; Bird Cast.cast(Object o)
        Cast.cast(o); //Doc提示: &lt;Object&gt; Object Cast.cast(Object o) 

        Fish f=Cast.cast(b); //Doc提示:&lt;Fish&gt; Fish Cast.cast(Object o) //!!ClassCastException
}  

public static class Bird{} 
public static class Fish{} 

}



cast泛型方法是如何做类型推断的?
Bird b=Cast.cast(o); //cast如何推断出T就是Bird??!! 问题在这里
Cast.cast(o); //cast此时只能推断出T就是Object

难道区别在于有没有接收返回值,有的话,可以根据"="号左边的类型继续推断;没有的话,只能推断出cast方法的参数类型;

求详细解答 或 给予参考资料 OTZ


问题补充
七心JAVA 写道
Bird b=Cast.cast(o);
是不是得加个类型强制转换?

不需要,代码是从eclipse里拿出来的,java编译器可以通过
问题补充
IcyFenix 写道
嗯,实际上这里确实是有个强制转换的,只不过...

恩,请详细解释: Bird b=Cast.cast(o); //cast如何推断出T就是Bird??!! 问题在这里

所有的泛型信息都会被擦除掉,这么说绝对吗?
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • seicefire 2011-04-28 16:35
    已采纳

    LZ可参考一下这贴:http://www.iteye.com/topic/1021949

    单独一份讲泛型的资料应该无法全面说明你所问的问题,你这个问题的关键不在泛型,而在于编译器解语法糖时的泛型擦除过程。所以还需要讲一下javac(你这里实际上是ecj)是如何解语法糖的,但是那个太长了,贴出来不太方便,LZ先看看这个吧。

    已采纳该答案
    打赏 评论
  • wnsx241 2011-04-28 16:35

    Bird b=Cast.cast(o);
    是不是得加个类型强制转换?

    打赏 评论
  • seicefire 2011-04-28 16:35

    嗯,实际上这里确实是有个强制转换的,只不过不需要你自己手动去加,编译器在解语法糖的时候自动帮你添加了。

    main方法在解语法糖之后,实际上是这样的:
    [code="java"] public static void main(String[] args) {
    Object o = new Cast.Bird();
    Cast.Bird b = (Cast.Bird)cast(o);

    cast(o);
    
    Cast.Fish f = (Cast.Fish)cast(b);
    

    }[/code]

    而cast的方法描述符和(字节码级的)方法签名是这样的:
    // Method descriptor #15 (Ljava/lang/Object;)Ljava/lang/Object;
    // Signature: (Ljava/lang/Object;)TT;
    请注意,Method descriptor中,方法返回值就是Ljava/lang/Object而已,泛型被擦除掉了。

    至于你要的资料,我整理一下发一篇出来吧。

    打赏 评论
  • rednaxelafx 2011-04-28 16:40

    [quote="mwei"]难道区别在于有没有接收返回值,有的话,可以根据"="号左边的类型继续推断;没有的话,只能推断出cast方法的参数类型;[/quote]
    正是如此。在Java语言规范里有规定:
    [url=http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.2.8]15.12.2.8 Inferring Unresolved Type Arguments[/url]
    不只是等号赋值,作为参数传递的情况也算“赋值”因而也一样会用于推导。

    打赏 评论

相关推荐 更多相似问题