你能解释一下为什么//(?!)没有在行中抛出 ClassCastExeption 异常吗?There (T)is , where T=String, 这意味着 there (String) new Integer(42), 应该抛出异常...... JVM 应该转换类型,但由于某种原因它没有。然后我们看看类型t,看看Integer什么是真正的类型t。但是我们推断类型的事实表明没有抛出异常。然后程序在调用函数的地方抛出异常A.<String>f()。
顺便一提!我记得 Bruce Eckel 教过有一些 javap 反编译器,他自己使用字节码或 .class 编写程序代码……我没有研究它。如果有人精通这一点,请尝试让反编译器构建这段代码,也许它会显示那里真正发生了什么,为什么?
public class A {
public static <T> T f() {
T t = (T) new Integer(42); // (?!) ЧТО ЧЁРТ ВОЗЬМИ ЗДЕСЬ ВООБЩЕ ПРОИСХОДИТ?!
System.out.println(t.getClass());
return t;
}
public static void main(String[] args) {
System.out.println(A.<String>f()); // как здесь возможно исключение? ахаха, вы серьёзно?
}
}
新:
所以,朋友们。最常见的答案是,方法f()是已编译为常规方法的常规方法,但考虑到其调用结果被强制转换为传递为的类型这一事实<NameOfTheClass>。一切似乎都已经很好了,这个答案可以被接受,但如果它在 Java 中真的像这样工作......关键是你可以main(String[])尝试调用更具爆炸性的东西:
System.out.println(A.<Double>f());
令人惊讶的是,控制台会输出:
//output:
class java.lang.Integer
42
所以如果我们让它不可见,它看起来像这样:
System.out.println((Double)A.<Double>f());
然后尝试编译它 - 会出现错误啊哈哈哈,从那里得出的结论是它不能完全一样......
我对此的猜测是该方法println()被重载,并且在A.<String>f()它选择版本println(String arg)的情况下,并且在A.<Double>f()它理解Double没有版本并设置println(Object arg)它的情况下,因为对于我们的, 42 被(Object)Integer(42)调用.toString()并显示。
对我来说,奇怪的是,由于某种原因,在第一种情况下,当我们调用A.<String>f()它时,这里的许多人认为它是这样调用(String)A.<String>f()的,从它设置版本的位置开始println(String arg),而第二次调用时A.<Double>f(),它确实如此没有尝试这样做(Double)A.<Double>f(),它立即选择了println(Object arg)...。
您想说整个技术非常智能,如果println()成功检查参数化/泛型函数的返回是否作为重载方法中的参数存在,则不会调用强制转换[例如,String版本println()存在,是的,让我们将输出转换Object为A.f()指定的String],如果重载版本没有在类的类型参数中指定版本A.f(),println()那么它(编译器)离开版本println(Object)并决定不尝试(Object)(Double)A.<Double>f()做是结果f()本身Object吗?
总计:我想要解释参数化方法(类)是如何工作的,这样的解释是编译器对生成代码的操作的算法是清楚的。如果我对编译器操作的一些猜测是正确的,那么我希望他们(我的猜测)得到确认,并且非常希望(!)带有指向一些文档文件的链接!










