Cur*_*rds 5 java generics casting
因此,我有一个比较深奥的问题。我正在尝试创建一个有点通用但类型化的属性收集系统。它依赖于似乎是错误的核心假设。该代码说明了该问题:
import java.lang.Integer;
public class Test {
private static Object mObj = new String("This should print");
public static void main(String[] args ) {
String s = Test.<String>get();
System.out.println(s);
try {
// actual ClassCastException reported HERE
int i = Test.<Integer>get();
} catch ( ClassCastException e ) {
System.out.println("Why isn't the exception caught earlier?");
}
int i2 = getInt();
}
public static <T> T get() {
T thing = null;
try {
// Expected ClassCastException here
thing = (T)mObj;
} catch ( ClassCastException e ) {
System.out.println("This will *not* be printed");
}
return thing;
}
// This added in the edit
public static Integer getInt() {
return (Integer)mObj;
}
}
Run Code Online (Sandbox Code Playgroud)
编译并运行后,输出为
This should print
Why isn't the exception caught earlier?
Run Code Online (Sandbox Code Playgroud)
在静态方法“ get”中,我尝试转换为通用参数类型T。基础成员(mObj)为String类型。在第一次调用中,Generic参数为兼容类型,因此应用程序将适当地打印字符串。
在第二次调用中,Generic参数的类型为Integer。因此,get方法中的强制转换应该失败。我希望它会引发ClassCastException(打印语句“这将*不*将被打印”。)但是,这不会发生。
而是在尝试将返回值分配给变量“ i”时,在get方法返回之后引发强制转换异常。这是问题:
延迟投放错误的解释是什么?
**编辑**为了乐趣和完整性,我添加了一个非通用的getInt方法来说明我希望获得的响应。当编译器知道类型时,会发生什么呢?
这是因为get方法中的转换(应生成编译器警告)是未经检查的转换。编译器不知道什么T时候调用,thing = (T) mObj;所以它不知道强制转换是否应该编译。
编译后,由于类型擦除,生成的字节码调用get返回的方法Object(T擦除并替换为Object),并将类型转换简单地转换为:
Object thing = null;
try {
thing = mObj;
Run Code Online (Sandbox Code Playgroud)
从方法返回结果后即进行检查get,即int i = Test.<Integer> get();等同于:
Object o = Test.get();
int i = ((Integer) o).intValue();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |