[英]Why doesn't class ProcessBuilder override equals()?
我最近發現JDK6中的類ProcessBuilder不會覆蓋equals()
。 有原因嗎? 由於該類是可變的,我可以理解為什么它不會覆蓋hashCode()
。
我很驚訝地發現這段代碼不起作用:
ProcessBuilder x = new ProcessBuilder("abc", "def");
ProcessBuilder y = new ProcessBuilder("abc", "def");
if (x.equals(y)) { // they are never equal
// something important here
}
我查看了ProcessBuilder
類的JDK6源代碼,我沒有看到equals()
的覆蓋。
我覺得有一個更深層次的原因,超越這一課。 也許這是故意的?
除非它們是同一個對象,否則最好的做法是使可變對象不相等。 這是因為對象可能會在以后更改。 考慮以下
Set<ProcessBuilder> pbSet = new HashSet<>();
pbSet.add(x);
pbSet.add(y);
// if x and y were equal pbSet would have one element.
y.setSomething()
// should pbSet have one or two elements.
更糟糕的是,相反的情況是兩個物體可能不同但后來變得相同。 這意味着Set將有一個重復的對象。
有趣的是集合是可變的,但仍然有equals和hashCode。 我認為這種情況的原因是沒有不可變的集合。 例如,字符串覆蓋equals(),而StringBuilder則沒有。
補充@PeterLawrey的答案:對於本質上可變的對象,實現equals和hashcode在任何情況下都是有風險的。 您無法保證此類對象完全安全發布。 因此,這些類的作者只是“放棄”這些類的equals和hashcode是有道理的。
但是:如果你有理由相信你可以控制這種平等,那么你就有了一些東西: 番石榴的Equivalence
。 如果您可以確保對高度可變類的充分控制訪問,則允許您為這些對象定義equals / hashcode策略,以便您甚至可以在HashSet
使用它們。
關於這個Equivalence
更多信息:對於一個本質上可變的“不穩定”類X
,但是你可以在給定的上下文中保證等價,你實現了一個Equivalence<X>
。 然后你將這些X
實例“包裝”到例如:
Set<Equivalence.Wrapper<X>>
然后,您將使用以下命令添加到此集:
set.add(eq.wrap(x));
eq
是你實現Equivalence
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.