1

I have a class:

public class Foo {
 ...
}

I know if I don't override the toString() method & do following, it would print out the address of the instance of Foo:

Foo foo = new Foo();
System.out.println(foo); // this prints the address of foo

But if I override the toString():

public class Foo {
     ...
   @Override
   public String toString() {
      StringBuilder builder = new StringBuilder();
      builder.append("My customized string.");
      return builder.toString();
   }
}

same code would print out the string defined in the customized toString() method:

Foo foo = new Foo();

// this prints the "My customized string."
System.out.println(foo); 

What I want to achieve is to printout both the address and the customized string, I tried following:

public class Foo {
         ...
       @Override
       public String toString() {
          StringBuilder builder = new StringBuilder();
          builder.append("My customized string.");
          // return adress and the customized string
          return this + ", " + builder.toString();
       }
    }

But got exception:

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:698)
    at java.lang.StringBuilder.append(StringBuilder.java:214)

How can I print out both address and the customized string when calling System.out.println(foo) ?

Leem
  • 17,220
  • 36
  • 109
  • 159
  • 4
    The number you see when you use the default `toString` is **not** the object's address. – T.J. Crowder Jun 05 '19 at 17:00
  • 2
    It's not an address, it's a hex representation of the object's hash code. – azurefrog Jun 05 '19 at 17:01
  • Thanks for pointing out, but as long as it represent a identity to identify the object, it is fine. But my point is not that. but how to printout both. – Leem Jun 05 '19 at 17:02
  • 4
    It doesn't do that, either. There can be more than one object with the same hash code. – RealSkeptic Jun 05 '19 at 17:03
  • 2
    If you want a unique identifier for your objects, you need to give them unique identifiers. – T.J. Crowder Jun 05 '19 at 17:05
  • OK, then, why normally people judge that e.g. singleton gives the same object by compare this hex representation of hash code of the object? Do you mean that is a wrong way to judge whether two objects are the same? If so, what is the correct/reasonable way? – Leem Jun 05 '19 at 17:21
  • https://stackoverflow.com/questions/1360826/how-to-get-address-of-a-java-object/27634397#27634397 – Jainil Patel Jul 26 '19 at 04:28

1 Answers1

3

I know if I don't override the toString() method & do following, it would print out the address of the instance of Foo:

No, it wouldn't. The number you see in the default toString is the object's hash code in hex, see Object::toString, which is return getClass().getName() + '@' + Integer.toHexString(hashCode());.

Note that this number is not necessarily unique. It's a hash code, not an ID.

How can I print out both address and the customized string when calling System.out.println(foo) ?

You can include the default string in the string you return from your overridden version:

public String toString() {
   StringBuilder builder = new StringBuilder();
   builder.append("My customized string.");
   builder.append(":");              // ***
   builder.append(super.toString()); // ***
   return builder.toString();
}

or if you just want the number, do what Object::toString does:

public String toString() {
   StringBuilder builder = new StringBuilder();
   builder.append("My customized string.");
   builder.append(":");                                  // ***
   builder.append(Integer.toHexString(this.hashCode())); // ***
   return builder.toString();
}
azurefrog
  • 10,785
  • 7
  • 42
  • 56
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • If that number is not necessarily unique, why normally people judge that singleton gives the same object by compare this hex representation of hash code of the object? Do you mean that is a wrong way to judge whether two objects are the same? If so, what is the correct/reasonable way? – Leem Jun 05 '19 at 17:23
  • @Leem - Why? Because people have it stuck in their heads that that's the object address. :-) To judge whether two objects are the same, if you have the objects, use `==` and `!=`. If you need to have a unique identifier in strings, you need to give the objects a unique identifier. – T.J. Crowder Jun 06 '19 at 06:10
  • [`Object::hashCode`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html#hashCode()) does say *"As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (The hashCode may or may not be implemented as some function of an object's memory address at some point in time.)"* but note the caveats on that. "As much as reasonably practical" and "may or may not." Also note that the address of an object can change over time, but barring changes to object state, hashCode is supposed to be stable. :-) – T.J. Crowder Jun 06 '19 at 06:14