【发布时间】:2017-10-29 20:30:52
【问题描述】:
static <T> void f1(Base arg1, T arg2) {
T loc = (T) arg1; // why Derived is "kind of cast" to String?
System.out.println(loc.getClass().getName()); // would print: Derived
}
f1(new Derived(), "sdf"); // T is String - inferred from arg2
class Base { }
class Derived extends Base { }
我的想法是否正确:编写强制转换 (T) 的意思是“编译器不能也不会检查这个强制转换”。 在编译时编译器不知道 arg2 是什么(它可以是任何东西),因此编译器不能排除强制转换可以工作并且必须信任程序员。因此,这个演员表只是在编译时从未检查过。 在运行时本地 var 声明看起来像 Object loc = arg1;(在类型擦除之后)。所以一切正常,只是因为编译器从不关心这个 (T) 转换?
P.S:我的研究:this 和 this。 This is also very interesting ("casting primitive to generic": (T) true) 我的问题更明确地指出了这个问题,问题也是关于编译器是否检查了转换(T)并且代码示例中没有分心有问题。
【问题讨论】:
-
我不确定你在这里问什么:你是说编译器在给出这段代码时会做什么?它是否编译?
-
显式强制转换总是受信任的。当然,程序员经常会背叛这种信任。
-
@AndyTurner 你是对的。这不是 100% 的时间。我更多的是考虑涉及泛型的情况。
-
试图回答它,它超出了编译器的能力来现场检查演员表。但是,当您尝试调用特定类型的内容时,jvm 最终会检查类型。是你想知道的吗?
-
在未来,类型擦除会走得更远。运行时类型将出现;例如,
List<int>有努力,所以语言仍然没有僵化。