Почему класс ProcessBuilder не переопределяет equals()?

Недавно я обнаружил, что класс ProcessBuilder в JDK6 не переопределяет 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
}

Я посмотрел в исходный код JDK6 для класса ProcessBuilderи я не вижу переопределения для equals(),

У меня есть ощущение, что есть более глубокая причина, помимо этого одного класса. Возможно, это намеренно?

2 ответа

В дополнение к ответу @PeterLawrey: для объектов, которые изменчивы по своей природе, реализация equals и hashcode рискованна в любом случае. Вы не гарантируете, что такие объекты безопасно опубликованы вообще. Поэтому имеет смысл, что авторы таких классов просто "отказались" от равенства и хэш-кода для таких классов.

ОДНАКО: если вы достаточно уверены, что можете контролировать это равенство, то для вас есть что-то: Guava'sEquivalence, Если вы можете обеспечить достаточно контролируемый доступ к сильно изменяемым классам, это позволит вам определить стратегию равенства / хэш-кода для таких объектов, чтобы вы могли даже использовать их, скажем, в HashSet,

Подробнее об этом Equivalence: для "нестабильного" класса X который является изменчивым по своей природе, но для которого вы можете гарантировать эквивалентность в данном контексте, вы реализуете Equivalence<X>, Затем вы "оберните" эти случаи X например, в:

Set<Equivalence.Wrapper<X>>

Затем вы добавите в этот набор, используя:

set.add(eq.wrap(x));

где eq ваша реализация Equivalence,

Лучше всего делать изменяемые объекты не равными, если они не являются одним и тем же объектом. Это потому, что объект может измениться позже. Рассмотрим следующее

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. Я думаю, что причина этого в том, что нет неизменных коллекций. например, переопределение строки равно (), StringBuilder нет.

Другие вопросы по тегам