【问题标题】:what must be hashcode of null objects in Java?Java中空对象的哈希码必须是什么?
【发布时间】:2014-02-03 18:37:33
【问题描述】:

根据来自此post 的评论,null objectshascode 可以throw NPEzero 的值。这是特定于实现的。但在同一个实现中,为什么 Objects.hashcodehascode(instance) 返回不同的值。例如:

public class EqualsTesting {

    public static void main(String[] args){
        String p1 =null;
        String p2 = null;
        System.out.println(Objects.hashCode(p1));
        System.out.println(p2.hashCode());

    }
}

输出:

0
Exception in thread "main" java.lang.NullPointerException
    at BinaryTrees.EqualsTesting.main(EqualsTesting.java:14)

如果是这种情况,这不会影响HashMap 中的key look-up,其中null Key-value pairs 是允许的。 (可能是hashbucket 0throw a NPE

【问题讨论】:

  • 因为第一个是静态方法,第二个是非静态
  • @tintinmj:那他们为什么要返回不同的值呢?
  • 你不能在null上调用hashCode()或任何其他方法。
  • 您不能调用null 引用的任何实例方法。这并不特定于 hashCode() 方法。
  • “根据这篇文章的评论...” - 我建议您不要尝试过多地阅读单行评论。阅读真正的答案。

标签: java object hashmap hashcode


【解决方案1】:

你将如何计算一个甚至不存在的对象的hashCode?当p2null 时,对其调用任何方法都会抛出NPE。这并没有给你任何特定的 hashCode 值。

Objects.hashCode() 只是一个包装器方法,它对null 值执行预检查,对于不是null 的引用,它返回与本例中的p2.hashCode() 相同的值。以下是该方法的源代码:

public static int hashCode(Object o) {
    return o != null ? o.hashCode() : 0;
}

【讨论】:

  • HashMap 是否使用 Objects.hasCode() 计算 null 的哈希值?
  • @eagertoLearn:不,看看我的回答,对此有特殊处理。
  • @eagertoLearn 不,它没有。它只是将值0 用于null 键。
  • @eagertoLearn 如果你想知道它是如何实现的,你可以随时查看任何数据结构的源代码。源代码与您安装的 jdk 一起分发。
  • HashMap 是在 Objects 助手类之前编写的。如果Objects 存在,HashMap 可能已经使用了它。
【解决方案2】:

根据这篇文章的评论,空对象的 hascode 可以抛出 NPE 或零值。

那不是真的。 (这不是@Bohemian 的评论所说的!)

HashMapHashSet 中发生的情况是它们将null 视为一种特殊情况。他们没有在 null 对象上调用 hashcode()(这将是 NPE !!),而是使用零作为硬编码的替代哈希码。

我强调...这是HashMapHashSet 的特例行为...不是hashcode()

如您的示例所示,如果您确实尝试在null 上调用hashcode() 方法,您得到一个NPE。 JLS 说这就是将要发生的事情......并且每当您尝试在 null 上调用 any 实例方法时都会发生这种情况。

(另一方面,Objects.hashCode(obj) 方法确实objnull 的情况作为一种特殊情况处理。这就是静态方法的全部意义所在!)

【讨论】:

  • 那么为什么它像 Bohemian 评论的那样是特定于实现的?
  • 它特定于您正在实施的任何实施,您如何处理此问题。在HashMap / HashSet 的情况下,value 用作null 对象的ersatz 哈希值也是特定于实现的。但是,为了满足 javadoc,HashMapHashSet 的实现不能允许(假设的)NPE 在null 情况下访问用户代码。
【解决方案3】:

正如the javadoc 所说:

Objects.hashCode(Object o)

返回非空参数的哈希码,0 表示空 论据。

p2.hashCode() 抛出 NullPointerException,因为您试图访问空对象的方法。

【讨论】:

    【解决方案4】:

    如果您四处搜索,您会注意到HashMap 有一个special handling 对应null 键。 null 值很好,因为您不会在 HashMap 中为它们计算哈希码。这就是null 键在HashMap 中正常工作的原因。至于为什么Objects.hashCode 可以正常工作,看看 Rohit 的回答。

    【讨论】:

    • 另外@sanjay null 检查在 hashmap put() 方法中完成。如果为 null,则从 put 调用一个单独的方法。
    【解决方案5】:

    null的哈希码为0(见Objects.hash()

        public static int hashCode(Object a[]) {
            if (a == null)
                return 0;
    
            int result = 1;
    
            for (Object element : a)
                result = 31 * result + (element == null ? 0 : element.hashCode());
    
            return result;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-10-21
      • 2013-08-02
      • 1970-01-01
      • 2013-06-18
      • 2020-01-20
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      相关资源
      最近更新 更多