了解类型擦除,我认为this cast不会在运行时编译或工作:
public class GenericDatumReader<D> implements DatumReader<D> {
...
@SuppressWarnings("unchecked")
public D read(D reuse, Decoder in) throws IOException {
return (D) read(reuse, actual, expected != null ? expected : actual, in);
}
然而,它有效!
程序如何在运行时知道D
是什么?
修改
我写了一个简单的测试:
1 public class Main {
2
3 public static class Something<D> {
4
5 private Object getObj() { return new Object(); }
6 private String getStr() { return new String("hello"); }
7
8 public <D> D get(boolean str) {
9 return (D) (str ? getStr() : getObj());
10 }
11 }
12
13 public static void main(String[] args) {
14 Something<String> something = new Something<>();
15 String str = something.get(true);
16 String notStr = something.get(false);
17 }
18 }
如果没有(D)
强制转换,则无法编译:
Main.java:9: error: incompatible types: bad type in conditional expression
return (str ? getStr() : getObj());
^
String cannot be converted to D
where D is a type-variable:
D extends Object declared in method <D>get(boolean)
Main.java:9: error: incompatible types: bad type in conditional expression
return (str ? getStr() : getObj());
^
Object cannot be converted to D
where D is a type-variable:
D extends Object declared in method <D>get(boolean)
2 errors
使用(D)
演员,我只会获得一个未经检查的警告,但它会编译。但是,在运行时:
$ java Main
Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to java.lang.String
at Main.main(Main.java:16)
答案 0 :(得分:3)
这里有两个方面:
D
是Object
,所以返回的值实际上可能是{{}} {1}} - 编译器无法确定。D
在运行时是什么,因此强制转换根本不做任何事情。如果非泛型方法将结果分配给运行时已知的某种类型(即非泛型),那么如果该对象的类型不正确,则可能会创建强制转换异常。