Gar*_*son 12 java uri equals hashcode
Java Object契约的一个基本部分是该hashCode()方法应该与该equals()方法一致.这是有道理的并且易于理解:如果两个对象在某种程度上"相等",则它们应该返回相同的哈希码.如果没有,你可以将一个对象放在一个HashSet,例如,然后检查一个单独的实例是否在集合中并错误地返回false,即使该equals()方法会认为对象是等价的.
事实上,从Java 6开始,Java的URI代码就存在这个问题.试试这段代码:
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()));
}
}
Run Code Online (Sandbox Code Playgroud)
根据RFC 3968,URI转义序列不区分大小写; 也就是说,%2A和%2a被认为是等同的.Java URI.equals()实现将此考虑在内.但是,URI.hashCode()实施并没有考虑到这一点!这意味着,返回两个URI的实例true为URI.equals()但可以返回不同的散列码,如在示出的代码以上!
我提交了这个问题,据说导致了Java Bug 7134993,但该bug已不再可用.但是,Java Bug 7054089中显示了同样的问题.(我不确定这是来自我的提交还是来自其他人,但问题是相同的.)然而,该错误被评估拒绝,"引用的示例是不透明的URI,因此特定于方案的部分不是解析".
评估此错误的人必须不熟悉它的含义equals()并hashCode()保持一致.Object.equals()明确规定的合同,"如果两个对象根据equals(Object)方法相等,那么在两个对象中的每一个上调用hashCode方法必须产生相同的整数结果." 注意使用"必须"而不是"应该".
这里的要点是,即使评估者声称URI是"不透明的"和"未解析的",URI.equals()实现(与他/她的主张相反)确实解析了URI并允许不区分大小写.该URI.hashCode()执行不.
所以我在这里完全密集并且遗漏了一些明显的东西吗?如果我是,有人请告诉我我的错误,我会将你的答案标记为正确.否则,问题是:现在Sun/Oracle似乎不再允许对提交的错误进行评论,我有什么办法可以获得对互联网主要标识符的Java实现中的这个基本问题的认可和行动,即URI?
好消息!Oracle 似乎已经在JDK-7171415中修复了 Java 8 的这个错误!我已经验证我的上述测试现在在 Windows 10 Pro 64 位上的 Java 1.8.0_92 中通过。新的错误单没有引用任何以前的错误单,所以我不知道它是如何发生的。但我很高兴他们终于修好了。
| 归档时间: |
|
| 查看次数: |
635 次 |
| 最近记录: |