The instanceof
operator checks whether the given object is a sublcass (not necessarily a true subclass) of the given class. This does in general mean that you can cast the object to that class (reduce the view to it).
So for example if we have an ArrayList
we could cast it to List
, also instanceof
would return true
if we check that ArrayList
against List
. So in your example of course you could do
new C() instanceof B // true
new B() instanceof A // true
However the classes also inherit such properties from their parents. Thus the class C
is of course also subclass of A
, since it is subclass of B
and B
is subclass of A
, so we get
new C() instanceof A // true
And the same holds for interfaces too, we get
new A() instanceof I // true
and by inheritance
new B() instanceof I // true
new C() instanceof I // true
Practical example
Take a look at the following example
public interface CanBark { }
public class Dog implements CanBark { }
public class Pug extends Dog { }
of course the Pug
is a Dog
and since Dog
is a CanBark
the Pug
is also a CanBark
, we get
new Pug() instanceof Dog // true
new Dog() instanceof CanBark // true
new Pug() instanceof CanBark // true
Details of instanceof
The Java Language Specification (§15.20.2) defines the behavior of the instanceof
operator as
At run time, the result of the instanceof
operator is true
if the value of the RelationalExpression is not null
and the reference could be cast
(§15.16) to the ReferenceType without raising a ClassCastException
. Otherwise the result is false
.
Whereas the cast
(§15.16) behaves like
[...] or checks, at run time, that a reference value refers to an object whose class is compatible with a specified reference type.
Therefore the casting refers to the casting rules specified in (§5.5). Your specific case is defined in (§5.5.1) as
If T
(target) is an interface type:
If S
(source) is not a final class (§8.1.1), then, if there exists a supertype X
of T
, and a supertype Y
of S
, such that both X
and Y
are provably distinct parameterized types, and that the erasures of X
and Y
are the same, a compile-time error occurs.
Otherwise, the cast is always legal at compile time (because even if S
does not implement T
, a subclass of S
might).