javatostringapache-commonsapache-commons-langapache-commons-lang3

Why does ToStringBuilder work inconsistently?


In the following code, why do the two lines containing System.out.println(person); yield different outputs? The second line indirectly calls the method Job.toString yielding the string "Manager", but the first line mysteriously does not yielding Job@28f67ac7. The line in between person.put("a", "b"); doesn't seem to me like it should make any difference.

Code:

import java.util.*;
import org.apache.commons.lang3.builder.*;

class Job extends HashMap<String, String> {
    @Override public String toString() {
        return "Manager";
    }
}

class Person extends HashMap<String, String> {
    Job job;

    Person() {
        this.job = new Job();
    }

    @Override public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

class Test {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);
        person.put("a", "b");
        System.out.println(person);
    }
}

Console:

Person@2b80d80f[job=Job@28f67ac7,threshold=0,loadFactor=0.75]
Person@2b80d80f[job=Manager,threshold=12,loadFactor=0.75]

Solution

  • 2 things contribute to the output changing:

    This means while person and person.job in your example remain equal to each other, ToStringBuilder will not call person.job.toString(), but when the map contents change, person.job.toString() will be called.