Проверка контрактов в Java - встроенная? Например. Хэш-код / ​​равно

Есть ли встроенная проверка контрактов в Java, например. для контракта между хэш-кодом и функцией равенства?

В этом вопросе давайте возьмем в качестве примера контракт hashcode / equals, но меня интересует проверка контрактов в целом. Я читал в нескольких местах, что равно и хэш-код должен удовлетворять «контракту» в Java:

  • Равные должны соответствовать трем правилам отношения эквивалентности, а также должны быть согласованы при повторных вызовах.
  • Равные объекты подразумевают одинаковые хэш-коды

Я понимаю условия, и они мне понятны. Однако мне интересно, является ли это просто контрактом, записанным на бумаге - по сути, сильным руководством для разработчиков, чтобы не писать ошибочный код - или это что-то, что будет обнаружено Java как исключение времени компиляции или выполнения?


person Colm Bhandal    schedule 13.10.2017    source источник
comment
Это не будет обнаружено Java как исключение времени компиляции или выполнения. Вы несете ответственность за соблюдение условий контракта (написание кода).   -  person nbokmans    schedule 13.10.2017
comment
Если равно одинаковым, это не означает, что хэш-код совпадает, тогда вы можете получить какое-то странное поведение. Например. один и тот же объект может быть сопоставлен с разными сегментами хэш-карты.   -  person Tim Biegeleisen    schedule 13.10.2017
comment
Спасибо, ребята, вот что я подумал. Так что, по сути, это серьезное указание для Java не писать код, который будет действительно ужасным и ошибочным ... НО мы все еще теоретически могли бы написать программу, которая нарушает контракт, и она могла бы компилироваться и работать нормально в течение многих лет, без каких-либо ошибок. становится очевидным.   -  person Colm Bhandal    schedule 13.10.2017
comment
@ColmBhandal Да   -  person khelwood    schedule 13.10.2017


Ответы (2)


Это не будет выполняться во время компиляции.

Некоторые классы могут обеспечивать такое поведение во время выполнения - например, вы можете написать метод, который проверяет, что два одинаковых объекта имеют одинаковый хэш-код, или отправляет исключение.

Также обратите внимание, что бывают ситуации, когда вы можете намеренно отклониться от рекомендованного контракта.

person assylias    schedule 13.10.2017
comment
Спасибо. Мне было бы действительно интересно увидеть пример, в котором действительно было бы желательно отклонение от этого контракта? - person Colm Bhandal; 13.10.2017
comment
Например, Comparable настоятельно рекомендует, чтобы compareTo соответствовал equals (т.е. (a.compareTo(b) == 0) == (a.equals(b)). Но есть случаи, когда отклонение от этой рекомендации полезно, например: stackoverflow.com/a/14534751/829571 - person assylias; 13.10.2017

Это не (и не может быть) автоматически обнаружено во время компиляции или выполнения (кроме случаев, когда вы явно проверяете это.

Примеры простых счетчиков:

public boolean equals(Object other){
    return new Random().nextInt(3) == new Random().nextInt(3);
}

public int hashCode() {
    return new Random().nextInt(3);
}

Однако рекомендуется создавать модульные тесты, проверяющие эти контракты. Я столкнулся с ошибками, которые было трудно обнаружить из-за использования плохо реализованного equals / hashcode.

person Viktor Mellgren    schedule 13.10.2017
comment
да, чем больше я думаю об этом, тем больше понимаю, что это не может быть обнаружено автоматически. Я вижу, что в Java есть фреймворки для правильных построений. Интересно, есть ли какие-либо фреймворки, которые пытаются проверить это нарушение контракта во время компиляции. Был бы интересный проект. - person Colm Bhandal; 13.10.2017
comment
Если вас что-то интересует в этом направлении, посетите en.wikipedia.org/wiki/Java_Modeling_Language - person Viktor Mellgren; 13.10.2017
comment
Хороший! Очень интересно. Похоже, это позволяет вам, по крайней мере, естественным образом указать эти контакты таким образом, как тройки Хоара, а затем это преобразуется в утверждения времени выполнения. Я сомневаюсь, что можно было бы написать инструмент в целом, который мог бы дать ответ ДА ​​/ НЕТ во время компиляции для любой спецификации JML, хотя, вероятно, это неразрешимая проблема, как и большинство этих общих вещей в компьютерных науках. Во всяком случае, очень интересно. Индустрия желаний использовала это больше. - person Colm Bhandal; 15.10.2017