Почему хеш-код java.net.URL разрешает хосту IP-адрес?
Есть две причины. Первое:
- Поведение класса
URL
было разработано для моделирования URL-адреса, являющегося локатором сетевого доступного ресурса. В частности, equals
и hashCode()
были разработаны так, чтобы два экземпляра URL
были равны, если они находят один и тот же ресурс. Для этого необходимо, чтобы DNS-имя было преобразовано в IP-адрес.
Оглядываясь назад, мы знаем следующее:
Метод URL.equals
не может 1 надежно определить, являются ли две строки URL локаторами для одного и того же ресурса. Причины включают виртуальный хостинг, пересылку HTTP 30x и внутреннее сопоставление URL-адресов на сервере и т. Д.
Поведение IP-разрешения URL.equals
и URL.hashcode
является ловушкой для неопытных Java-программистов, даже если оно четко задокументировано.
Даже в тех случаях, когда это приводит к правильному ответу, разрешение IP на URL.equals
может быть неожиданным (и нежелательным) ударом по производительности.
Короче ... этот аспект дизайна URL
был ошибкой.
Это подводит нас ко второй, более важной причине.
- Поведение
URL.equals(Object)
было определено долгое время назад, и было бы невозможно изменить сейчас, не нарушив (возможно) миллионы развернутых Java-приложений. Это исключает любую возможность того, что Sun (теперь Oracle) изменит его.
Возможно, разработчики (гипотетического) преемника библиотеки классов Java могли бы исправить это (и другие вещи). Конечно, для достижения этой цели обратная совместимость с существующими Java-программами должна быть выброшена из окна .
И, наконец, реальный ответ для разработчиков приложений на Java - просто использовать вместо этого класс URI. (Реальная разработка программного обеспечения заключается в том, чтобы выполнять работу как можно лучше, а не в том, чтобы жаловаться на инструменты, которые вам предоставили.)
1 - Когда я говорю «не могу» выше, я имею в виду, что это теоретически невозможно. Работа с некоторыми из более сложных случаев потребует изменений в протоколе HTTP. И даже если гипотетический HTTP 2.0 «исправит» проблему, мы все равно будем иметь дело с устаревшими серверами HTTP 1.1 через 20 лет ... и поэтому URL.equals
все равно будет сломан.