Java Reference
In-Depth Information
exception. One way to obviate this situation is to verify that the object is of the type you expect before you
make the cast.
You saw earlier in this chapter how you could use the
getClass()
method to obtain the
Class
object
corresponding to the class type, and how you could compare it to a
Class
instance for the class you are
looking for. You can also do this using the
instanceof
operator. For example, suppose you have a variable
pet
of type
Animal
, and you want to cast it to type
Duck
. You could code this as:
if(pet instanceof Duck) {
Duck aDuck = (Duck)pet; // It is a duck so the cast is OK
aDuck.layEgg(); // and You can have an egg for tea
}
If
pet
does not refer to a
Duck
object, an attempt to cast the object referenced by
pet
to
Duck
causes an
exception to be thrown. This code fragment executes the cast and lay an egg only if
pet
does point to a
Duck
object. The preceding code fragment could have been written much more concisely as:
if(pet instanceof Duck) {
((Duck)pet).layEgg(); // It is a duck so You can have an egg for tea
}
So what is the difference between this and using
getClass()
? Well, it's quite subtle. The
instanceof
operator checks whether a cast of the object referenced by the left operand to the type specified by the right
operand is legal. The result is
true
if the object is the same type as the right operand,
or of any subclass
type
. You can illustrate the difference by choosing a slightly different example.
Suppose
pet
stores a reference to an object of type
Spaniel
. You want to call a method defined in the
Dog
class, so you need to check that
pet
does really reference a
Dog
object. You can check whether you have
a
Dog
object or not with the following statements:
if(pet instanceof Dog) {
System.out.println("You have a dog!");
} else {
System.out.println("It's definitely not a dog!");
}
You get confirmation that you have a
Dog
object here, even though it is actually a
Spaniel
object. This
is fine, though, for casting purposes. As long as the
Dog
class is in the class hierarchy for the object, the cast
works okay, so the operator is telling you what you need to know. However, suppose you write:
if(pet.getClass() == Dog.class) {
System.out.println("You have a dog!");
}
else {
System.out.println("It's definitely not a dog!");
}
Here the
if
expression is
false
because the class type of the object is
Spaniel
, so its
Class
object is
different from that of
Dog.class
— you would have to write
Spaniel.class
instead of
Dog.class
to get
the value
true
from the
if
expression.
You can conclude from this that for casting purposes you should always use the
instanceof
operator
to check the type of a reference. You only need to resort to checking the
Class
object corresponding to a
reference when you need to confirm the exact type of the reference.