第一个决议之后的想法是否依赖于操作系统缓存?这似乎效率低下,并且在多个域解析为相同IP的情况下,这是不正确的。我错过了什么?
答案 0 :(得分:22)
为什么java.net.URL的哈希码会将主机解析为IP?
有两个原因。第一个是:
URL
类的行为旨在模拟作为网络可访问资源定位器的URL。具体而言,equals
和hashCode()
的设计使得两个URL
实例在找到相同资源时是相等的。这要求将DNS名称解析为IP地址。 事后看来,我们知道以下内容:
URL.equals
方法不能 1 可靠地确定两个URL字符串是否是同一资源的定位符。原因包括虚拟主机,HTTP 30x转发和URL的服务器内部映射等。
URL.equals
和URL.hashcode
的IP解析行为是没有经验的Java程序员的陷阱,即使它已被清楚记录。
即使在导致正确答案的情况下,URL.equals
的IP分辨率也可能是意外(且不需要的)性能影响。
简而言之...... 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。