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 { }
我的想法是否正确:写 cast (T) 意味着“编译器不能也不会检查这个 cast”。 在编译时,编译器不知道 arg2 是什么(它可以是任何东西),因此编译器不能排除转换可以工作并且必须信任程序员。因此,这个转换在编译时从未被检查过。 在运行时本地 var 声明看起来像 Object loc = arg1;
(在类型删除之后)。所以一切正常只是因为编译器从不关心这个 (T) 转换? p>
P.S:我的研究:this , 和 this . This is also very interesting ("casting primitive to generic": (T) true) 我的问题更明确地指出了问题所在,问题还在于编译器是否检查了 cast (T) 并且相关代码示例中没有干扰。
最佳答案
这包含在 JLS Sec 5.5.1 中:
Given a compile-time reference type S(source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules.
...
If T is a class type, then either |S| <: |T|, or |T| <: |S|. Otherwise, a compile-time error occurs.
...
If T is a type variable, then this algorithm is applied recursively, using the upper bound of T in place of T.
因此编译器使用 Object
代替 T
,因此它认为转换是合法的。
关于java - 编译器从不检查强制转换为泛型类型 (T)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47004935/