Reputation: 38143
Having some idea of type erasure, I would think this cast would not compile or work at runtime:
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);
}
However, it works!
How does the program know at runtime what D
is?
EDIT
I wrote a simple test:
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 }
Without the (D)
cast, this doesn't compile:
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
With the (D)
cast I get just an unchecked warning but it compiles. However, at runtime:
$ 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)
Upvotes: 1
Views: 183
Reputation: 156469
There are two aspects here:
D
at compile-time is that it's an Object
, so it's perfectly possible that the returned value is actually going to be a D
--the compiler can't determine otherwise.D
is at run-time, so the cast doesn't do anything at all. If a non-generic method assigned the result to some type that was known at runtime (i.e. non-generic), then it could create a cast exception if the object was not of the right type.Upvotes: 3