Joker
Joker

Reputation: 11146

Needs information regarding type casting in Instanceof Operator

Following instanceof operator is working fine, when I type cast string to Object.

However, Without typecasting it is failing to compile.

public class Test {
        public static void main(String[] args) {
            boolean b1 = "abc" instanceof Integer; // Compilation fails
            boolean b2 = ((Object) "abc") instanceof Integer; // Works fine
        }
    }

My question is why compiler is rejecting the first one b1 but allowing the second one b2

Upvotes: 0

Views: 163

Answers (3)

Stephen C
Stephen C

Reputation: 718788

JLS 15.20 and 15.20.2 state this:

RelationalExpression:
  ...
  RelationalExpression instanceof ReferenceType

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error (§15.16), then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

In your first example expression ("abc" instanceof Integer) "abc" (a String) cannot be cast to Integer. Therefore the instanceof expression is a compilation error.

In your second example expression (((Object) "abc") instanceof Integer), the left operand has type Object. In some cases, an Object may be an Integer. Therefore the left-hand operand can be cast to the right-hand type. Therefore the instanceof is allowed.

It is worth noting that the JLS is only concerning itself with the compile-time types of the expressions. In the second example, we can easily deduce that the run-time type of the left hand operand is always String and the expression will always evaluate to false. But the JLS rules don't classify this "mistake" as a compilation error.

Upvotes: 2

Andy Turner
Andy Turner

Reputation: 140318

Because you've casted "abc" to Object, the compiler treats ((Object) "abc") the same as any other expression of Object type.

As such, it thinks that it could contain any Object (or null). The compiler doesn't deeply inspect the expression to determine a more specific type.

You can also write:

Object obj = "abc";
boolean b2 = obj instanceof Integer;

It's basically the same.

It stops you writing "abc" instanceof Integer because both String and Integer are classes, and they are unrelated, so a String can never be an instance of an Integer. (It would allow "abc" instanceof List, because List is an interface, and it doesn't consider the final-ness of a class, and assumes there might be a subclass of String that could implement List).

In a sense, casting is you telling the compiler that you know more than it does. Although the compiler is able to push back in very basic cases where it can determine that you are doing something nonsensical, it largely gets out of the way and trusts you (in a "on your head be it" kind of way).

Upvotes: 5

verejava
verejava

Reputation: 17

Instanceof can only be used between parent and child classes

the first one "abc" is String type not Integer.
but the second one ((Object) "abc") is Object type, Integer is a child of Object

Upvotes: 0

Related Questions