Как получить распознавание ошибки URI hashCode() URI, которая была ненадлежащим образом отказана

Основная часть контракта Java Object заключается в том, что метод hashCode() должен соответствовать методу equals(). Это имеет смысл и легко понять: если два объекта "равны" каким-то образом, они должны возвращать один и тот же хэш-код. Если нет, вы можете, например, поставить один объект в HashSet, а затем проверить, будет ли отдельный экземпляр установлен в наборе и некорректно вернуться false, хотя метод equals() рассмотрел бы эквивалент объектов.

На самом деле код URI Java имеет эту проблему с Java 6. Попробуйте этот код:

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.net.URI;

import org.junit.Test;

public class URITest
{

    @Test
    public void testURIHashCode()
    {
        final URI uri1 = URI.create("http://www.example.com/foo%2Abar");
        final URI uri2 = URI.create("http://www.example.com/foo%2abar");
        assertThat("URIs are not equal.", uri1, equalTo(uri2));
        assertThat("Equal URIs do not have same hash code.", uri1.hashCode(), equalTo(uri2.hashCode()));
    }
}

Управляющие последовательности URI, как в RFC 3968, нечувствительны к регистру; т.е. %2A и %2A считаются эквивалентными. Реализация Java URI.equals() учитывает это. Однако реализация URI.hashCode() не учитывает это! Это означает, что два экземпляра URI, которые возвращают true для URI.equals(), тем не менее могут возвращать разные хэш-коды, как показано в приведенном выше коде!

Я представил эту проблему, которая предположительно приводит к ошибке Java 7134993, но эта ошибка больше не доступна. Тем не менее, эта же проблема показана в Java Ошибка 7054089. (Я не уверен, что это было из моего представления или от кого-то другого, но проблема такая же.) Однако ошибка была отклонена при оценке, . Приведенные примеры - непрозрачные URI, и поэтому конкретная схема детали не анализируются ".

Тот, кто оценил эту ошибку, должен быть не знаком с тем, что означает, что для equals() и hashCode() должно быть последовательным. В контракте для Object.equals() четко сказано: "Если два объекта равны в соответствии с методом equals (Object), то вызов метода hashCode для каждого из двух объектов должен давать одинаковый целочисленный результат". Обратите внимание на использование "must", а не "should".

Дело в том, что, хотя оценщик утверждает, что URI является "непрозрачным" и "не анализируется", реализация URI.equals() (вопреки его/ее утверждениям) действительно анализирует URI и делает скидку на случай нечувствительность. Реализация URI.hashCode() отсутствует.

Итак, я здесь совершенно плотный и пропуская что-то очевидное? Если я, кто-то, пожалуйста, просветите меня о моей ошибке, и я помету ваш ответ как правильный. В противном случае возникает вопрос: теперь, когда Sun/Oracle больше не допускает комментариев к поданным ошибкам, каким образом я должен получить признание и действия по этой фундаментальной проблеме в реализации Java первичного идентификатора Интернета, URI?

Ответ 1

Хорошие новости! Oracle, похоже, исправил эту ошибку для Java 8 в JDK-7171415! Я подтвердил, что мой тест выше теперь проходит в Java 1.8.0_92 на Windows 10 Pro 64-бит. Новый биг-код не ссылается ни на один из предыдущих, поэтому я не знаю, как это произошло. Но я рад, что они, наконец, исправили это.

Ответ 2

Я бы повторно представил ошибку против Java 1.7.0_17, используя приведенный здесь пример, а не тот, который указан в ошибке 7054089. Я проверил, что ваш пример StackOverflow также содержится в этой версии. Я слышал, что Oracle закрыла исправление ошибок на Java 6, за исключением проблем безопасности.

В исходной отправке ошибок URI, которые вы указали, являются непрозрачными URI, и это, возможно, отключило оценщика. И я думаю, вы имеете в виду RFC 2396.

Кроме того, вы можете получить новый оценщик:)

Мне кажется, что они определенно нарушили контракт для hashCode() здесь.

И стыдно, что у них нет механизма StackOverflow, такого как комментарий для Java (или основных комментариев, как в прошлом).