【问题标题】:Why does ToStringBuilder work inconsistently?为什么 ToStringBuilder 工作不一致?
【发布时间】:2018-08-05 08:38:07
【问题描述】:

在以下代码中,为什么包含 System.out.println(person); 的两行会产生不同的输出?第二行间接调用方法Job.toString 产生字符串"Manager",但第一行神秘地没有产生Job@28f67ac7person.put("a", "b"); 之间的界线在我看来并没有什么不同。

代码:

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);
    }
}

控制台:

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

【问题讨论】:

  • 我可以建议像这样扩展HashMap 几乎肯定没有你想象的那么有用。 Person 不是 HashMap;不过,它们可能具有HashMap 属性,因此组合在这里是更合适的关系。
  • @AndyTurner 我同意,扩展 HashMap 在这个例子中没有用。但是考虑到这个例子是人为的,你会期望得到不一致的输出吗?
  • @BrianSchack 不,我不会。除了 ToStringBuilder 类的糟糕实现之外,我看不出这种行为的合乎逻辑的解释。
  • @cricket_007 Override 注释是可选的。我添加了它,但它不会改变输出。
  • @AndyTurner 是的,我担心我可能偶然发现了 Apache Commons 中的一个错误。我一直在阅读源代码,但似乎找不到它的位置。

标签: java tostring apache-commons apache-commons-lang apache-commons-lang3


【解决方案1】:

有两件事导致输出变化:

  • ToStringBuilder 避免在相等的实例上调用 toString() 以避免无限递归。
  • 你的 Person 和 Job 类继承了 HashMap 的 equals() 方法,导致new Person().equals(new Job()) == true

这意味着当示例中的 person 和 person.job 保持相等时,ToStringBuilder 不会调用 person.job.toString(),但是当地图内容发生变化时,会调用 person.job.toString()。

【讨论】:

  • 感谢您的解释!
猜你喜欢
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多