Java 为什么ToString Builder的工作不一致?
在下面的代码中,为什么这两行包含Java 为什么ToString Builder的工作不一致?,java,tostring,apache-commons,apache-commons-lang,apache-commons-lang3,Java,Tostring,Apache Commons,Apache Commons Lang,Apache Commons Lang3,在下面的代码中,为什么这两行包含System.out.println(person)产生不同的输出?第二行间接调用方法Job.toString生成字符串“Manager”,但第一行神秘地没有生成Job@28f67ac7。介于person.put(“a”、“b”)之间的一行对我来说似乎没有什么区别 代码: 有两件事导致输出发生变化: toString Builder避免在相等实例上调用toString(),以避免无限递归 Person和Job类继承HashMap的equals()方法,导致new
System.out.println(person)代码>产生不同的输出?第二行间接调用方法Job.toString
生成字符串“Manager”
,但第一行神秘地没有生成Job@28f67ac7
。介于person.put(“a”、“b”)之间的一行代码>对我来说似乎没有什么区别
代码:
有两件事导致输出发生变化:
- toString Builder避免在相等实例上调用toString(),以避免无限递归
- Person和Job类继承HashMap的equals()方法,导致
newPerson().equals(newjob())==true
这意味着,当示例中的person和person.job保持相等时,toString Builder将不会调用person.job.toString(),但当映射内容更改时,将调用person.job.toString()。我是否可以建议像这样扩展HashMap
几乎肯定没有您想象的那么有用。Person
不是HashMap
;不过,它们可能有一个属性的HashMap
,因此组合在这里是更合适的关系。@Andy Turner我同意,扩展HashMap在本例中没有用处。但是考虑到这个例子是人为的,你会期望得到不一致的结果吗?@BrianSchack不,我不会。除了ToStringBuilder
类的实现不佳之外,我看不到对这种行为的任何逻辑解释。@cricket\u 007覆盖注释是可选的。我添加了它,但它并没有改变输出。@AndyTurner是的,我担心我可能在Apache Commons中偶然发现了一个bug。我一直在阅读源代码,但我似乎找不到它在哪里。谢谢你的解释!
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]