Java 编译器从未检查转换为泛型类型(T)? static void f1(基准arg1,T arg2){ T loc=(T)arg1;//为什么派生为字符串的“类型转换”? System.out.println(loc.getClass().getName());//将打印:派生 } f1(新派生(),“sdf”);//T是从arg2推断的字符串 类基{} 类派生扩展基{}
我的想法正确吗:编写cast(T)意味着“编译器无论如何不能也不会检查此cast”在编译时,编译器不知道arg2是什么(它可以是任何东西),因此编译器不能排除强制转换可以工作,并且必须信任程序员。因此,在编译时永远不会检查此强制转换运行时本地变量声明类似于Java 编译器从未检查转换为泛型类型(T)? static void f1(基准arg1,T arg2){ T loc=(T)arg1;//为什么派生为字符串的“类型转换”? System.out.println(loc.getClass().getName());//将打印:派生 } f1(新派生(),“sdf”);//T是从arg2推断的字符串 类基{} 类派生扩展基{},java,generics,casting,Java,Generics,Casting,我的想法正确吗:编写cast(T)意味着“编译器无论如何不能也不会检查此cast”在编译时,编译器不知道arg2是什么(它可以是任何东西),因此编译器不能排除强制转换可以工作,并且必须信任程序员。因此,在编译时永远不会检查此强制转换运行时本地变量声明类似于对象loc=arg1(在类型擦除之后)。所以一切正常,仅仅因为编译器从不关心这个(T)强制转换 我的研究:,和。(“casting primitive to generic”:(T)true)我的问题更明确地指出了这个问题,这个问题还涉及到ca
对象loc=arg1代码>(在类型擦除之后)。
所以一切正常,仅仅因为编译器从不关心这个(T)强制转换
我的研究:,和。(“casting primitive to generic”:(T)true)我的问题更明确地指出了这个问题,这个问题还涉及到cast(T)是否由编译器检查,并且在所讨论的代码示例中是否没有干扰。这一点在:
给定编译时引用类型S(源)和编译时引用类型T(目标),如果由于以下规则没有发生编译时错误,则存在从S到T的转换
如果T是一个类类型,那么| S |
在编译时,编译器不知道arg2是什么(它可以是任何东西),因此编译器不能排除强制转换可以工作,并且必须信任程序员
我宁愿说编译器不知道什么是t
。例如,可以是对象
,在这种情况下,演员阵容将是合法的。在这种情况下,设计师决定更倾向于允许可能非法的造型,而不允许可能合法的造型
另一个问题是编译器无法生成实际的“转换到t
”,因为JVM只有“转换到特定类”指令。因此,cast似乎在运行时也成功了
如果您确实想要进行选中强制转换,可以通过将Class
作为额外参数传递来实现:
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 { }
static void f1(基本arg1,类clazz){
T loc=clazz.cast(arg1);//将引发异常
System.out.println(loc.getClass().getName());
}
在你的情况下,你可以写作
static void f1(基准arg1,T arg2){
T loc=(T)arg2.getClass().cast(arg1);
System.out.println(loc.getClass().getName());
}
找出在什么情况下它与前面的代码不同应该是有指导意义的。我不确定您在这里问什么:您说编译器在给出此代码时会做什么?它是否编译?显式强制转换始终受信任。当然,程序员经常背叛这种信任。@AndyTurner你是对的。这不是100%的时间。我更多地考虑涉及泛型的情况。试图回答这个问题,编译器无法当场检查强制转换。但是,当您尝试调用特定于类型的东西时,jvm最终会检查类型。这是你想知道的吗?在未来,类型擦除只会走得更远。运行时类型将出现;例如,
列表
需要努力,因此该语言仍然没有僵化。
static <T> void f1(Base arg1, Class<T> clazz) {
T loc = clazz.cast(arg1); // will throw exception
System.out.println(loc.getClass().getName());
}
static <T> void f1(Base arg1, T arg2) {
T loc = (T) arg2.getClass().cast(arg1);
System.out.println(loc.getClass().getName());
}