interface Printable {}
class BlackInk {}
public class Main {
public static void main(String args[]) {
Printable printable = null;
BlackInk blackInk = new BlackInk();
printable = (Printable)blackInk;
}
}
If the preceding code is compiled and run, the result is a ClassCastException at printable = (Printable)blackInk;
. But, if Printable is changed to a class, it doesn't compile because blackInk can't be cast to Printable. Why does it compile when Printable is an interface?
The compiler does not know that this won't work: You could have a subclass of BlackInk that implements Printable. Then the cast would be fine.
In situations where the compiler knows it won't work, you will get an error.
For example, if you make BlackInk final
(so that there can be no subclasses) you get an error.
According to java language specification section: 5.5.1 Reference Type Casting:
For a compile-time reference type S
(source) and a compile-type reference type T
(target); While casting conversion from S
to T
, If S
is a class
Type
If
T
is aClass
type:- Then either
T
is a subtype ofS
orS
is a subtype ofT
. Otherwise, a compile time error occurs. if there exists a supertype
X
ofT
, and a supertypeY
ofS
, such that bothX
andY
are provably distinct parameterized types, and that the erasures ofX
andY
are the same, a compile-time error occurs.class S{} class T extends S{} //// S s = new S(); T t = (T)s; // run time ClassCastException will happen but no compile time error
- Then either
If
T
is anInterface
type:- If
S
is not afinal
class, then, if there exists a supertypeX
ofT
, and a supertypeY
ofS
, such that bothX
andY
are provably distinct parameterized types, and that the erasures ofX
andY
are the same, a compile-time error occurs. Otherwise, the cast is always legal at compile time (because even ifS
does not implementT
, a subclass ofS
might) - If S is a final class, then S must implement T, or a compile-time error occurs.
- If
That is for your case, even if class casting is detected in compile time, Interface casting is detected in runtime
.
Type casting happens at run time
(remember run time polymorphism). At compile time compiler doesn't see anything wrong with the code and compiles and at run time it tries to type cast blackink
to printable
and is unable to do so as blackink
doesn't implement printable
, hence the error.
来源:https://stackoverflow.com/questions/19824941/why-does-it-compile-when-casting-to-an-unrelated-interface