3

Here is my example code:

String str = "hello";
Object obj = (Object)str;
System.out.println(obj.toString());

I found the source code of Object, and the toString() method is:

public String toString() {   
   return getClass().getName() + "@" + Integer.toHexString(hashCode());
} 

I thought the result of the example shound be the address of this Object, like [B@15db9742 , after I convert str to Object , but it still print hello. Why? Shoundn't obj use the method of Object? Can Anyone explain the principle of it to me?

C-Otto
  • 5,615
  • 3
  • 29
  • 62
Chestnut
  • 29
  • 5
  • 5
    Welcome to [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)). :-) *(There must be a dupetarget for this.)* – T.J. Crowder May 09 '17 at 10:00
  • *Method Overriding* - You are changing only the reference type, the actual object is *still a String* and the `toString` of `String` returns the actual string – TheLostMind May 09 '17 at 10:00
  • 1
    Please have a look at this question: http://stackoverflow.com/questions/321864/java-dynamic-binding-and-method-overriding – C-Otto May 09 '17 at 10:01
  • ...and yet I'm not finding a really good one. But that just has to be me running out of time to search. – T.J. Crowder May 09 '17 at 10:05
  • You are not *converting* a `String` to an `Object` - you are *casting* (and in this case, the cast isn't even necessary, you could just do `Object obj = str;` without casting). Casting does not change (i.e. convert) an object. – Jesper May 09 '17 at 11:04

4 Answers4

5

This is polymorphism (specifically, runtime polymorphism). It doesn't matter what the type of your reference to the object is (Object or String), as long as that type has toString (so your code compiles), the toString that will be used is the one the object itself actually has, not necessarily the one provided by the type of your reference. In this case, the object is a String no matter what the type of your reference to it is, so String#toString is used.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

Because the underlying object is a String object and the String class has overridden the toString() method in it.

Though you have the type Object on left hand, the methods from implemented Class gets execute and the overall phenomenon called as Polymorphism. You are Just changing the Form of String to Object.

When you do

Object obj = (Object)str;

That doesn't change String to Object class. You are just changing the type of the Object not the actual behaviour of it.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
1

Virtual method invocation implies the method override will be executed given the actual implementation, as opposed to the implementation in the reference type.

In other words, your String instance will still invoke overrides of Object's methods implemented in String, even if cast as Object.

Mena
  • 47,782
  • 11
  • 87
  • 106
0

Object obj is the result of an (unnecessary) cast, but is still a String.... the String class has an implemented overide of toString method:

public String toString() {
    return this;
}

verify that obj is a String by doing:

System.out.println(str.getClass());
System.out.println(obj.getClass());

you will get

class java.lang.String

class java.lang.String

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97