gudii9
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
Why we use instanceof operator in java in down casting only not in upcasting. How ClassCastException are generated?
please advise
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The check happens while the code is running (i.e., not during compilation).
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
}
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.
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?
}
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
}
Doug
ASKER
The compiler sees what you see:''down cast is clear.
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
}
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)
Make sense?Doug
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.
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.
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
other rare scenario where child reference assigned with parent object which is down cast ,,possible runtime classcast exception without instanceof operator check
ASKER
package com.upcast;above down cast failed as below
public class ClassCAst {
public static void main(String args[])
{
Object ob=new Integer(10);
// ClassCastException occurs
System.out.println("The value is "+(String)ob);
}
}
Exception in thread "main" java.lang.ClassCastExcepti
at com.upcast.ClassCAst.main(
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.
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");
}
}
passed downcast line
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");
}
}
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.
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");
}
}
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.
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.
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
ASKER