In chapter 4 of S&B SCJP Study guide there is a section on the fact that the instanceof operator results in a compilation error because:
You can't use the instanceof operator to test across two different class hierarchies.
and gives the following code:
which results in a compilation error.
This has got me really confused. I mean I thought that that was the whole point of the instanceof operator. To test whether this particular instance was of a particular type or not. If I pass an reference to an instance of a Dog where there should have been an instance of a Cat then I want the result to be a false value, not for the whole of the code to break. It seems a bit harsh.
So does instanceof only work when it is possible that you are comparing two types that have some sort of polymorphic link? In other words before you use the instanceof operator, you have to know that the two operands have some sort of polymorphic relationship.
The first instanceof comparison which gives you an error, will be false in all the circumstances. It can never be true (there cannot be an object which is both Dog and Cat as they are both classes and multiple inheritance is not supported in java). So why would anyone write a condition which will always be false??
which is fine. Having written the code I know that Dog is not in the same hierarchy as Cat, so one is not inheriting from another, so you can't use a reference variable of one to reference and instance of the other.
What I had been thinking was that there could be a situation where you don't know if the type of your reference variable is in the same hierarchy as another type or not, but you pass it as a parameter anyway, because you think that the worse that could happen is that you will get a false returned after using the instanceof operator.
But the instanceof operator is to test the instance, not the reference variable, so using it requires you to know that there is at least a possibility of a true value being returned. ie. you have to know that the instance that is assigned to the reference variable IS-A whatever-the-reference-variable-type before you use instanceof to test to see exactly what type it is. I think.
According to your second example, Object, Dog, Cat may be in a hierarchy. (Cat extends Object and Dog also extends Object) And your variable d(Object) in second coding refers Dog object, but it can also refers any other object.
If I simplify my question, How does the second code work?
|BSc in Electronic Eng| |SCJP 6.0 91%| |SCWCD 5 92%|
Joe Lemmer wrote:What I had been thinking was that there could be a situation where you don't know if the type of your reference variable is in the same hierarchy as another type or not, but you pass it as a parameter anyway, because you think that the worse that could happen is that you will get a false returned after using the instanceof operator.
That's right, there could be a situation like that. But this is not one of those situations. The compiler can tell that a Cat object -- which can be any subclass of Cat -- can never be a Dog.
Now if Cat were an interface, and not a class, then it could be possible for a subclass of Dog to implement the Cat interface. In that case you'd have a Dog which "IS A" Cat, and the compiler won't complain. Of course, as you say, you might still get "false" at run time. However you might not have come across this case (the interface business) in your studies yet, but you probably will.
posted 10 years ago
Thanks Paul for clarifying.
Abimaran, if Paul hasn't already answered your question, then I will try, but I'm still learning like you so, please take that into account.
I think that in order to use the instanceof operator it has to at least be possible for the second operand to be of the type of the first operand. So,
in the above code, the first operand is 'd', which as we know is an Object reference variable. As all instances will be of type Object or a subclass of Object, then it is always legal to use the instanceof operator (it will compile).
Whereas, in the example code from the S&B book:
the first operand 'd' is of type Dog. The compiler knows that Cat has not extended Dog. This is important because this means that, as people have pointed out above, as a class can only extend one class (Java doesn't support multiple inheritence), then a sub-type of Dog will never be able to pass the IS-A test for Cat. Therefore the compiler knows that the object referenced (by the Dog object reference) will never pass the instanceof test, so this causes a compile time error.
I hope that is clear, and also that that is right. Thank you to everyone whose post have helped me to understand this.