toString() Method

String representation of objects

4 min read

toString() Method in Java

The toString() method returns a string representation of an object. It's called automatically in string contexts and is essential for debugging.

When toString() is Called

  • System.out.println(object)
  • String concatenation: "Info: " + object
  • String.valueOf(object)
  • Logging frameworks
  • Debugger displays

🔑 Best Practice: Always override toString() in your classes. The default output (className@hashCode) is not useful!

Code Examples

Default toString is not useful

java
1// Default toString() - not useful
2public class Person {
3    private String name;
4    private int age;
5    
6    public Person(String name, int age) {
7        this.name = name;
8        this.age = age;
9    }
10}
11
12Person p = new Person("Alice", 25);
13System.out.println(p);  // Person@15db9742 - not helpful!
14System.out.println(p.toString());  // Same thing
15
16// Default implementation in Object class:
17// getClass().getName() + "@" + Integer.toHexString(hashCode())

Override toString() for useful output

java
1// Overriding toString() - useful output
2public class Person {
3    private String name;
4    private int age;
5    private List<String> hobbies;
6    
7    public Person(String name, int age, List<String> hobbies) {
8        this.name = name;
9        this.age = age;
10        this.hobbies = hobbies;
11    }
12    
13    @Override
14    public String toString() {
15        return "Person{" +
16               "name='" + name + '\'' +
17               ", age=" + age +
18               ", hobbies=" + hobbies +
19               '}';
20    }
21}
22
23Person p = new Person("Alice", 25, List.of("Reading", "Gaming"));
24System.out.println(p);
25// Person{name='Alice', age=25, hobbies=[Reading, Gaming]}
26
27// Automatic call in concatenation
28String info = "User: " + p;
29System.out.println(info);
30// User: Person{name='Alice', age=25, hobbies=[Reading, Gaming]}

StringBuilder for complex toString()

java
1// Using StringBuilder for complex toString()
2public class Order {
3    private String orderId;
4    private List<String> items;
5    private double total;
6    private boolean shipped;
7    
8    @Override
9    public String toString() {
10        StringBuilder sb = new StringBuilder();
11        sb.append("Order {\n");
12        sb.append("  orderId: ").append(orderId).append("\n");
13        sb.append("  items: ").append(items).append("\n");
14        sb.append("  total: $").append(String.format("%.2f", total)).append("\n");
15        sb.append("  shipped: ").append(shipped).append("\n");
16        sb.append("}");
17        return sb.toString();
18    }
19}
20
21// Output:
22// Order {
23//   orderId: ORD-001
24//   items: [Laptop, Mouse]
25//   total: $1299.99
26//   shipped: false
27// }
28
29// Or use String.format()
30@Override
31public String toString() {
32    return String.format("Order[id=%s, items=%d, total=$%.2f]", 
33        orderId, items.size(), total);
34}

IDE generation and library options

java
1// IDE generation and libraries
2// Most IDEs can auto-generate toString()
3
4// Using Lombok (annotation processor)
5import lombok.ToString;
6
7@ToString
8public class Product {
9    private String name;
10    private double price;
11}
12// Auto-generates: Product(name=X, price=Y)
13
14@ToString(exclude = "password")  // Exclude sensitive fields
15public class User {
16    private String username;
17    private String password;
18}
19
20// Using Apache Commons
21import org.apache.commons.lang3.builder.ToStringBuilder;
22
23@Override
24public String toString() {
25    return ToStringBuilder.reflectionToString(this);
26}
27
28// Java Records (Java 16+) - auto toString()
29public record PersonRecord(String name, int age) {
30    // toString() auto-generated: PersonRecord[name=X, age=Y]
31}

Use Cases

  • Debugging and logging
  • Error messages with object info
  • User-friendly display
  • Data inspection in tests
  • Console output
  • Log file analysis

Common Mistakes to Avoid

  • Not overriding toString()
  • Including sensitive data (passwords)
  • Circular references causing StackOverflow
  • Calling methods that may fail
  • Too verbose or too terse output
  • Not handling null fields