Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
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 - Fatal编程技术网

Java 编译器从未检查转换为泛型类型(T)? static void f1(基准arg1,T arg2){ T loc=(T)arg1;//为什么派生为字符串的“类型转换”? System.out.println(loc.getClass().getName());//将打印:派生 } f1(新派生(),“sdf”);//T是从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

我的想法正确吗:编写cast(T)意味着“编译器无论如何不能也不会检查此cast”在编译时,编译器不知道arg2是什么(它可以是任何东西),因此编译器不能排除强制转换可以工作,并且必须信任程序员。因此,在编译时永远不会检查此强制转换运行时本地变量声明类似于
对象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());
}