Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

instanceof operator in java

Hi,

Why we use instanceof  operator in java in down casting only not in upcasting. How ClassCastException  are generated?
please advise
SOLUTION
Avatar of CPColin
CPColin
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

use a runtime check like the instanceof operator
why instanceof is called runtime check?
The check happens while the code is running (i.e., not during compilation).
Avatar of gudii9

ASKER

how to for which operators happens at compile time and for which operators happen at run time? any other operators apart from instanceof that happens at runtime? any examples for operators for which check happens at compile time?
It's not really an important distinction to make. When you think about it, all operators happen at runtime, right? But they're also checked for proper syntax at compile time. If you have a specific question about an operator, I can answer that. Beyond that, we're getting to concepts that probably aren't useful.
ASKER CERTIFIED SOLUTION
Avatar of dpearson
dpearson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

Integer x = new Integer(5) ;
Object y = x ;   // Upcast - compiler knows "x" is an Object so allows this//WHY COMPILER KNOWS HERE
Integer z = y ; // Downcast - compiler doesn't know that y is actually an Integer so rejects this//WHY COMPILER DOES NOT KNOW HERE...WHY THIS IS CALLED DOWNCAST HERE WITHOUT KNOWING WHAT Y IS?
Integer a = (Integer)y ; // Runtime cast - but may throw an exception (maybe y is not an Integer)?//WHY COMPILER NOT SURE ON Y IF INTEGER OR NOT

if (y instanceof Integer) {  // Runtime check
   Integer a = (Integer)y ;   // Safe cast - we know y is an Integer here so this will work
}
The compiler knows, at compile time, every superclass and interface in the hierarchy of any given type. Because it knows this, it can check upcasts at compile time. The compiler does not know everything that extends or implements a given type, so downcasts are always a runtime check. The JVM knows, at runtime, the exact type hierarchy of every object in memory (otherwise it wouldn't be able to instantiate them), so it's well-equipped to handle the runtime type checks.
Avatar of dpearson
dpearson

WHY COMPILER NOT SURE ON Y IF INTEGER OR NOT

Like CPColin said.

The compiler sees what you see:

public void check(Object y) {
   Integer a = y ;          // What type of object is y?
}

Open in new window

It could be an Integer, it could be a String.
You can't tell and neither can the compiler - so it rejects this.

At runtime, "y" will be a specific instance (like Integer(25) or String("Hello")) and then you can tell whether this is OK or not.  But only at runtime.

If we want the compiler to trust us that this will be OK we tell it:

public void check(Object y) {
   Integer a = (Integer)y ;          // Trust me, y will be an Integer when we get here
}

Open in new window

Doug
Avatar of gudii9

ASKER

The compiler sees what you see:

public void check(Object y) {
   Integer a = y ;          // What type of object is y?
}

Select all
 
Open in new window
It could be an Integer, it could be a String.
You can't tell and neither can the compiler - so it rejects this.

At runtime, "y" will be a specific instance (like Integer(25) or String("Hello")) and then you can tell whether this is OK or not.  But only at runtime.

If we want the compiler to trust us that this will be OK we tell it:

public void check(Object y) {
   Integer a = (Integer)y ;          // Trust me, y will be an Integer when we get here
}

''down cast is clear.


not clear on upcast yet


Object y = x ;   // Upcast - compiler knows "x" is an Object so allows this//How COMPILER KNOWS HERE??
''down cast is clear.
Excellent.


Integer x ;
Object y = x ;   // Upcast - compiler knows "x" is an Object so allows this//How COMPILER KNOWS HERE??

OK the key here is that the compiler knows the class hierarchy - it can see this part of the code:
public class Integer extends Number {
}
and then Number extends Object {
}

So we have:
 Integer extends Number extends Object

So:
Integer x ;
Object y = x ;  // OK
Number z = x ; // Also OK
String a = x ; // Not allowed (Integer does not extend String)

Open in new window

Make sense?

Doug
Avatar of gudii9

ASKER

OK the key here is that the compiler knows the class hierarchy - it can see this part of the code:
public class Integer extends Number {
}
and then Number extends Object {
}


so compiler is designed and prebuilt such a way that it understands all the class hierarchy starting from Integer to number to Object??(only for built in classes like Interger right not for custom classes we write like Customer.Person??
The compiler, at compile time, knows the entire type hierarchy of every type, all the way up to Object, even for custom classes. Otherwise, it wouldn't be able to compile the code.
Avatar of gudii9

ASKER

Integer x ;
Object y = x ;  // OK
Number z = x ; // Also OK
String a = x ; // Not allowed (Integer does not extend String)

above is up cast right?

public void check(Object y) {
   Integer a = (Integer)y ;          // Trust me, y will be an Integer when we get here
}

above is down cast right?
i am confused with jargon up and down.

LHS(left hand side)=RHS(right hand side)
if we are assigning RHS Subclass to LHS  super class then up casting which checked at compile time code wont suddenly break at run time?

if we are assigning RHS Superclass to LHS  sub class then down casting? unless we use instaceof code may break at runtime as compiler cannot spot at compile time??


what is up wha is down hard remember in brain. just have to by heart?
by heart
Learned by rote; memorized word for word.
Avatar of gudii9

ASKER

we always assign to parent reference variable with child object which is common and compiler takes care of it right which is up cast...
other rare scenario where child reference assigned with parent object which is down cast ,,possible runtime classcast exception without instanceof operator check
Avatar of gudii9

ASKER

package com.upcast;

public class ClassCAst {

      
                public static void main(String args[])
                {
               
                Object ob=new Integer(10);

                // ClassCastException occurs
                System.out.println("The value is "+(String)ob);

                       
                }
            }

above down cast failed as below

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
      at com.upcast.ClassCAst.main(ClassCAst.java:12)



how to fix this with instanceof?
If you wrap that line in a conditional like if (ob instanceof String), the downcast won't be attempted unless it will succeed.
Avatar of gudii9

ASKER

package com.upcast;

public class ClassCAst {

	
		    public static void main(String args[])
		    {
		    
		    Object ob=new Integer(10);

		    // ClassCastException occurs
		    if (ob instanceof String)
		    System.out.println("The value is "+(String)ob);
		    System.out.println("passed downcast line");

		            
		    }
		}

Open in new window


passed downcast line
Avatar of gudii9

ASKER

package com.upcast;

public class ClassCAst {

	
		    public static void main(String args[])
		    {
		    
		    Object ob=new Integer(10);//upcast fine

		    // ClassCastException occurs
		    if (ob instanceof String)
		    System.out.println("The value is "+(String)ob);
		    System.out.println("passed downcast line");

		            
		    }
		}

Open in new window


Object ob=new Integer(10);//upcast fine

above is upcast right where as below is down cast?
  System.out.println("The value is "+(String)ob);
Yes.
Avatar of gudii9

ASKER

package com.upcast;

public class ClassCAst {

	
		    public static void main(String args[])
		    {
		    
		    Object ob=new Integer(10);//upcast fine

		    // ClassCastException occurs
		    if (ob instanceof String)
		    System.out.println("The value is "+(String)ob);
		    System.out.println("passed downcast line");

		            
		    }
		}

Open in new window

but String an Integer are not like super, sub classes right? they are more like peers so should we technically call it like peer casting rather than down casting?
You're casting an Object reference into a String reference, so it's a downcast. Just because the actual object is an instance of Integer doesn't change that fact. Basically, if it's not an upcast (which the compiler determines), it's a downcast.
Avatar of gudii9

ASKER

You're casting an Object reference into a String reference

is Object is big or String is big just to imagine and relate like physical size , cast, foundry  forgemanufactoring terminology ?
If you still had so many questions about this subject, why did you already assign points? I don't know that bringing manufacturing terminology into this discussion is going to help with the concepts at all.
Avatar of gudii9

ASKER

sure. cast means my mind goes that direction. I was under impression that sub class should be big compared to parent class. But it seems other way