在问答里提问,没有得到答案,特开此贴讨论。
代码如下:
public class Cast {public static <T> T cast(Object o){ return (T)o; } public static void main(String[] args){ Object o =new Bird(); Bird b=Cast.cast(o); //cast方法上的Doc提示:<Bird> Bird Cast.cast(Object o) Cast.cast(o); //Doc提示: <Object> Object Cast.cast(Object o) Fish f=Cast.cast(b); //Doc提示:<Fish> Fish Cast.cast(Object o) //!!ClassCastException } public static class Bird{} public static class Fish{}
}
LZ可参考一下这贴:http://www.iteye.com/topic/1021949
单独一份讲泛型的资料应该无法全面说明你所问的问题,你这个问题的关键不在泛型,而在于编译器解语法糖时的泛型擦除过程。所以还需要讲一下javac(你这里实际上是ecj)是如何解语法糖的,但是那个太长了,贴出来不太方便,LZ先看看这个吧。
Bird b=Cast.cast(o);
是不是得加个类型强制转换?
嗯,实际上这里确实是有个强制转换的,只不过不需要你自己手动去加,编译器在解语法糖的时候自动帮你添加了。
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而已,泛型被擦除掉了。
至于你要的资料,我整理一下发一篇出来吧。
[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]
不只是等号赋值,作为参数传递的情况也算“赋值”因而也一样会用于推导。