1

I thought the following code would compile and print "No"

class One{
 public static void main(String[] args) {

   One o = new One();
   if(o instanceof Two) {
     System.out.println("Yes");
   } else {
     System.out.println("No");
   }
 }
}

class Two { }

But it is throwing me a compiler error stating inconvertible types shouldn't the instanceof operator check if the object is in the inheritence hierarchy and return true if so, and false if not

Edit:

if it is a case of compiler already knowing that a certain condition can never be true and it throws a compiler error why is this code compiling

if(false) {
  System.out.println("Yes");
}
Thirumalai Parthasarathi
  • 4,541
  • 1
  • 25
  • 43
  • 2
    Because it can tell from the class names that the answer is false. Declare o to be an Object (but still create a One). `Object o = new One();` – Hot Licks Oct 01 '13 at 12:37
  • @fvrgl : i didn't see that post, my bad. but can you see my edit and provide an explanation? – Thirumalai Parthasarathi Oct 01 '13 at 12:44
  • You didn't violate any rules in the if(false) case. – Hot Licks Oct 01 '13 at 15:30
  • The JLS states: *If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, 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.* – Hot Licks Oct 01 '13 at 15:33
  • @HotLicks : i said "throws a compiler error" and inconvertable scenario won't be throwing any exceptions only compiler errors. maybe my usage of the throws is wrong here.. the JLS quote really made me understood the point.. :) – Thirumalai Parthasarathi Oct 01 '13 at 15:33
  • 1
    The JLS is pretty explicit and to the point. – Hot Licks Oct 01 '13 at 15:34

4 Answers4

4

You are getting that message because the compiler is able to tell that o cannot be an instance of Two because classes One and Two have no inheritance relationship.

Maybe you meant to write:

Object o = new One();

In that case your test would make sense.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55
4

I believe it's because you have declared your "o" variable as being of the "One" type. Change your code to this, and it should compile

   Object o = new One();
   if(o instanceof Two) {
     System.out.println("Yes");
   } else {
     System.out.println("No");
   }

The instanceof operator is meant to be used when you don't know the type in advance. So when you have an object of something that comes in through a method parameter, or when your variable is declared with the type of a base class and want to have different behavior per subclass type. In the scenario you've provided, the compiler can tell you at compile time that what you wrote will never be true, and does so.

Edit: the if(false) compiles, because a lot of people use a pattern like this:

public class Application{

    private static final boolean DEBUG = true;

    public static void main(String args[]){
        if(DEBUG){
            System.out.println("Debugging information");
        }
    }
}

Now imagine a large application where this sort of pattern is repeated in several places. If the compiler would refuse to compile this, it would be much harder to switch from and to DEBUG mode.

In my earlier explanation, maybe I shouldn't have used the words "the compiler can tell you at compile time that what you wrote will never be true". A better description would be "The compiler can tell that what you're writing does not make sense".

Moeri
  • 9,104
  • 5
  • 43
  • 56
0

instanceof is used to identify objects polymorphically referenced by a reference variable of another class, so if the reference variable o is not able to reference to an object of class Two it won't compile.

So this:

One o = new One();
if(o instanceof Two) {
    System.out.println("ok");
}

as a matter of example would be an error similar to this:

int i = 1;
if (i == "s") {
    System.out.println("ok");
}

It can't compile at all!

EDIT

An example of polymorphism where it would make your code compile (as per other's answers):

Object o = new One();

because o can reference to Two, so instanceof will tell you if it does or not.

Math
  • 3,334
  • 4
  • 36
  • 51
-1

First of all for above program you will get "Incompatible conditional operand types One and Two" because One and Two do not have any relationship.

To make above program result as True it should be like,

public class One {
    public static void main(String[] args) {

        One o = new Two();
        if (o instanceof Two) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}

class Two extends One {
}

Here, One is parent and Two is child. Parent referring to child object there fore instance of operator will return true.