为什么java.net.URL的哈希码将主机解析为IP?

时间:2010-02-27 18:08:52

标签: java url

第一个决议之后的想法是否依赖于操作系统缓存?这似乎效率低下,并且在多个域解析为相同IP的情况下,这是不正确的。我错过了什么?

4 个答案:

答案 0 :(得分:22)

  

为什么java.net.URL的哈希码会将主机解析为IP?

有两个原因。第一个是:

  • URL类的行为旨在模拟作为网络可访问资源定位器的URL。具体而言,equalshashCode()的设计使得两个URL实例在找到相同资源时是相等的。这要求将DNS名称解析为IP地址。

事后看来,我们知道以下内容:

  1. URL.equals方法不能 1 可靠地确定两个URL字符串是否是同一资源的定位符。原因包括虚拟主机,HTTP 30x转发和URL的服务器内部映射等。

  2. URL.equalsURL.hashcode的IP解析行为是没有经验的Java程序员的陷阱,即使它已被清楚记录。

  3. 即使在导致正确答案的情况下,URL.equals的IP分辨率也可能是意外(且不需要的)性能影响。

  4. 简而言之...... URL的设计方面是错误的。

    这给我们带来了第二个更重要的原因。

    • URL.equals(Object)的行为是在很久以前定义的,如果不破坏(可能)数百万个已部署的Java应用程序,现在就无法进行更改。这排除了Sun(现在的Oracle)将改变它的任何可能性。

    也许Java类库的(假设的)继承者的设计者可以解决这个问题(以及其他问题)。当然,向后兼容现有的Java程序必须抛出窗口才能实现这一点。

    最后,Java应用程序开发人员的真正答案是简单地使用URI类。 (真正的软件工程就是尽可能地完成工作,而不是抱怨你提供的工具。)


    1 - 当我说“不能”时,我的意思是理论上不可能。处理一些更困难的情况需要更改HTTP协议。即使假设的HTTP 2.0“修复”了这个问题,我们仍然会在20年内处理遗留的HTTP 1.1服务器......因此URL.equals仍会被破坏。

答案 1 :(得分:7)

很多人认为这是一个非常糟糕的主意。

以下是Javadoc of URI的一些解释。 这个question也很有用。

答案 2 :(得分:4)

请勿使用java.net.URL。这是你问题的简单答案。请改用java.net.URI,而不会执行主机名解析。

答案 3 :(得分:3)

hashCode()equals()密切相关。有关此行为的说明在equals()的文档中有所描述,如下所示:

  

如果是,则认为两台主机是等效的   两个主机名都可以解析成   相同的IP地址;否则,如果是   主机无法解析主机名   名字必须相等而不考虑   案件;或两个主机名等于   空。

来源:java.net.URL.equals() docs。