🏗️ Classes & Objects · Intermediate

toString() in Java

Default ClassName@hash and overriding it for readable output.

🧩 The mysteryYou print your shiny new Player object and get Player@6d06d69c. That's not a bug — it's Java politely asking you to finish your class.

Every object can describe itself

Every class inherits toString() from Object. The default returns the **class name, an @, and the hash code in hex** — getClass().getName() + "@" + Integer.toHexString(hashCode()). Accurate, but useless to humans.

Override it

Give your class a readable toString. It must be public String toString() — and @Override lets the compiler double-check the signature.

class Point {
    int x, y;
    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }
}

Who calls it?

You rarely call toString() yourself. println(obj) calls it (via String.valueOf, which prints "null" for null), "P=" + obj calls it, and collections call it on every element when they print themselves.

🔮 Predict it

A hand of cards

What does this print?

class Card {
    String r;
    Card(String r) { this.r = r; }
    public String toString() {
        return "[" + r + "]"; }
}
void main() {
    Card a = new Card("A"), b = new Card("K");
    System.out.println(List.of(a, b));
}
  1. [[A], [K]]
  2. [A, K]
  3. [Card, Card]
Show the answer

[[A], [K]]. The List prints its own brackets and calls toString() on each Card, which adds the inner brackets.

🔮 Predict it

Printing nothing

What does this print?

Object o = null;
System.out.println(o);
System.out.println("x=" + o);
  1. null x=null
  2. Throws NullPointerException
  3. x=
Show the answer

null and x=null. Neither println nor + calls toString() on a null reference — both convert it to the text "null".

⚠️ The trap

Forgot public

Object.toString() is public, and an override can't reduce visibility. Without public, your method is package-private, and the class doesn't compile: "attempting to assign weaker access privileges".

class Point {
    String toString() { // error!
        return "pt";
    }
}
💼 In the real world

In real projects

Good toString() methods make logs and debugger views readable — Order{id=42, total=19.99} beats Order@1f32e575. Records generate one for you. Watch out: never include passwords or tokens, because toString output ends up in log files.

Key takeaways

  1. Default: ClassName@hexHashCode
  2. println(obj) and "" + obj call toString()
  3. Override as public String toString()
  4. Collections print their elements' toString()
🤯 Did you know?

The hex number in Dog@1b6d3586 is a hash code, not a memory address. The garbage collector can even move the object in memory while that number stays the same.

Practice questions

What does Object's default toString() return?

  1. The class name, an @ and the hash code in hex
  2. All field names and values
  3. The object's memory address in decimal
  4. An empty String
Check your answer

The class name, an @ and the hash code in hex. It is getClass().getName() + "@" + Integer.toHexString(hashCode()), for example Dog@1b6d3586. That's why you override it.

What does this print?

class Point {
    int x = 1, y = 2;
    @Override
    public String toString() {
        return "(" + x + ", " + y + ")";
    }
}
void main() {
    System.out.println("P=" + new Point());
}
  1. P=(1, 2)
  2. P=Point@1b6d3586
  3. P=
  4. Compile error
Check your answer

P=(1, 2). Concatenating an object with a String calls its toString(), and this class overrides it to show the coordinates.

Next: the JDK has two classes called Date. How does Java know which one you mean?