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

2022-09-02 23:11:44

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


答案 1

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

有两个原因。首先是:

  • 该类的行为旨在将 URL 建模为网络可访问资源的定位器。具体来说,并且被设计为如果两个实例位于同一资源时相等。这要求将 DNS 名称解析为 IP 地址。URLequalshashCode()URL

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

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

  2. 对于没有经验的Java程序员来说,和 的 IP 解析行为是一个陷阱,即使它有明确的文档记录。URL.equalsURL.hashcode

  3. 即使在导致正确答案的情况下,IP分辨率也可能成为意外(和不需要的)性能损失。URL.equals

总之。。。设计的这一方面是一个错误。URL

这就引出了第二个更重要的原因。

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

也许Java类库的(假设的)继任者的设计者可以解决这个问题(以及其他事情)。当然,为了实现这一目标,必须与现有Java程序的向后兼容性被抛出窗外

最后,对于 Java 应用程序开发人员来说,真正的答案是简单地使用 URI 类。(真正的软件工程是关于尽可能地完成工作,而不是抱怨你获得的工具。


1 - 当我在上面说“不能”时,我的意思是这在理论上是不可能的。处理一些更困难的情况需要对HTTP协议进行更改。即使某些(假设的)未来版本的HTTP“修复”了问题,我们仍然会在20年后处理传统的HTTP服务器......因此,URL.equals 仍然会被破坏。


答案 2

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

以下是来自 URI 的 Javadoc 的一些解释。这个问题也很有用。