Search code examples
javaoverridingsuperclasssubclassing

How to force call superclass implementation Object.toString() rather than subclass overriding implementation on an object in Java


Please note: I am not asking how to force all classes to override toString() in their source code. Please read the question carefully.

All classes in java extend the Object class. If any class has a toString() override, a call to Object.toString() will actually execute the overriding method.

For example:

String test = "StackOverflow";
Object testobj1 = (Object) test;
System.out.println(testobj1.toString()); // prints "StackOverflow"
Object testobj2 = new Object();
System.out.println(testobj2.toString()); // prints "java.lang.Object@<Object.hashcode() in hex>"

What I need is for a call to testobj1's toString() to actually execute the Object class's toString() method. Something like:

System.out.println( [[testobj1 as Object]] .toString()); // prints "java.lang.String@<Object.hashcode() in hex>"

I tried using:

System.out.println(testobj1.getClass().getName() + '@' + Integer.toHexString(testobj1.hashCode()));

But this also has the same problem as above. The hashCode() method is also overriden by String class, so it is executing String's hashCode(), not Object's hashCode().

Is it possible to call the overridden method, rather than the overriding method?

Please note: The use of String class is merely an example. Do not base your answer on the assumption that the object is always a String object.

Also assume: I have no access to the source code of classes, so I can't just remove toString() implementation from them or do things like creating an abstract class. This has to work for any object (including that of Java's own classes or any API like String, HashMap, HttpServlet, etc). This also means that I'm not looking for answers like these.


Solution

  • You need to use System.identityHashCode() to get the actual (original) hash code.

    Try this code:

    public static void main(String[] args) {
        String test = "StackOverflow";
        Object testobj1 = (Object) test;
        System.out.println(testobj1.toString()); // prints "StackOverflow"
        System.out.println(testobj1.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(testobj1)));
        System.out.println(test.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(test)));
        Object testobj2 = new Object();
        System.out.println(testobj2.toString()); 
        System.out.println(testobj2.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(testobj2)));
    }
    

    Output:

    StackOverflow
    java.lang.String@5d888759
    java.lang.String@5d888759
    java.lang.Object@2e6e1408
    java.lang.Object@2e6e1408