I have a simple foo
class, and I am able to cast to a collection interface (either Map
or List
) without any compiler error. Note that Foo
class does not implement any interface or extends any other class.
public class Foo {
public List<String> getCollectionCast() {
return (List<String>) this; // No compiler error
}
public Map<String, String> getCollection2Cast() {
return (Map<String, String>) this; // No compiler error
}
public Other getCast() {
return (Other)this; // Incompatible types. Cannot cast Foo to Other
}
public static class Other {
// Just for casting demo
}
}
Why does the Java compiler not return incompatible types error when I try to cast the Foo
class to a collection?
Foo
does not implement Collection
. I would expect an incompatible types error, because given the current Foo
class signature, this cannot be a Collection
.
It's not because they're collection classes, it's because they're interfaces. Foo
doesn't implement them, but subclasses of it could. So it's not a compile-time error, since those methods may be valid for subclasses. At runtime, if this
isn't of a class that implements those interfaces, naturally it's a runtime error.
If you change List<String>
to ArrayList<String>
, you'll get a compiler-time error for that, too, since a Foo
subclass could implement List
, but can't extend ArrayList
(since Foo
doesn't). Similarly, if you make Foo
final
, the compiler will give you an error for your interface casts because it knows they can never be true (since Foo
can't have subclasses, and doesn't implement those interfaces).