Search code examples
javacastingpolymorphismtype-erasure

Polymorphism, Casting to Object, and Type Erasure


This is / are my very first question/s on Stackoverflow and I hope you might help me out with an understanding problem that I am having right now.

Let's say I am doing this:

Object o = null;
String s = "Test";
System.out.println(o instanceof String); //This returns false
o = s;
System.out.println(o instanceof String); //This returns true

So far so good, but now when I do:

System.out.println( ((Object) o) instance of String) //Still prints true

So why does this statement print true even though inside the print I cast o back to an Object class? Even

System.out.println(((Object)o).getClass()) 

prints that o is of class String. Why so?

This leads to my second question which has to do with Generics and Type erasure. I looked at a code sample like this:

private static <T> T cast(Object i){
    return (T) i;
}

public static void main(String[] args){
    Object o = null;
    try{
        o = main.<Double> cast("Test");
    }catch(ClassCastException ex) {
        System.out.println("Could not cast properly");
    }

    System.out.println(o == null); //Prints false
    System.out.println(o instanceof String); //Prints true
    System.out.println(o instanceof Double); //Prints false
}

From my understanding of type erasure all generics T will be replaced with Object during runtime. When running the cast function what should happen is actually something along the lines of return (Object) i;. As my first question above, why does System.out.println(o instanceof String); print true? Shouldn't o be of type Object?

Looking forward to your answers, thank you :)!


Solution

  • So why does this statement print true even though inside the print I cast o back to an Object class?

    You're just casting the reference to Object. The actual object is still that of String type. And instanceof check is against the actual instance, not reference type.

    prints that o is of class String. Why so?

    getClass() methods return the Class instance of runtime object type.

    why does System.out.println(o instanceof String); print true?

    As you notice, you're passing a String type as argument to your cast() method. So, even though the reference type is Object, again the actual object is of type String. Nothing special is going on here due to generics. The reasoning is same, and the result is also the same.