Reputation: 48
A co-worker showed me this code and I know it won't work (In fact, at runtime throws ClassCastException
when you run it).
I don't know why it compiles, because it cast from
java.io.FileInputStream
to org.springframework.core.io.InputStreamSource;
none of them implements the same interfaces or extends the same classes in hierarchies.
try (InputStream fileInputStream = new FileInputStream("somefile")) {
InputStreamSource file = (InputStreamSource) fileInputStream;
// some code
} catch (IOException e) {
// some code
}
Link of respective documentation classes: FileInputStream , InputStreamSource
Upvotes: 2
Views: 99
Reputation: 1074188
I don't know why it compiles...
Because it's an explicit cast between a non-final
reference type and an interface. An explicit cast between reference types says to the compiler: "Look, I (the programmer) know that this cast will be valid at runtime. Trust me." So it does. Later at runtime, of course, since the programmer was wrong, it fails.
The compiler doesn't blindly trust the programmer, though. Details in §JLS5.5, but if the compiler can prove that it's impossible for the cast to be valid, it'll still reject the cast. It can't do that in your case, though, because InputStreamSource
is an interface, and FileInputStream
is a non-final
class. So the FileInputStream
could well be referring to some subclass object that implements InputStreamSource
. (Of course, we can tell from looking at it that it isn't, since it was just set to the result of new FileInputStream
. But the compiler doesn't look quite that hard, it only cares about the types involved in the casting.)
Upvotes: 4
Reputation: 76
Because it's an explicit cast. The compiler trusts you that the cast will be valide at runtime, so if it's not the case it fails.
Upvotes: 2