繁体   English   中英

Java相等性检查和调度算法

[英]Java equality check and dispatch algorithms

有时在我的代码中,我必须检查某个变量是否等于常量字符串。 例如:

if (foo.equals("CONST")) {
    stuff.do();
}

有时foo为null所以我得到了null指针异常。 一种解决方法是像这样简单地交换对象和参数:

if ("CONST".equals(foo)) {
    stuff.do();
}

我已经读到这与Java是一种调度语言有关,但是我不明白为什么。 如果foo为null,则将在null对象上调用方法,这将导致null指针异常。 它与单次调度(或多次调度,动态调度等)有什么关系? 这个问题与任何派遣概念有关吗?

不完全是,在第一种情况下,您要调用equals表示null会导致问题;在第二种情况下,您要在调用“ CONST”而不是null时,foo只是一个参数,而equals不会被调用。

  1. Java不是单一的调度语言。 它具有多重调度机制,也就是方法重载。
  2. 没错,对于示例代码,分派没有任何作用。

您所读的只是关于每个对象都是Object.class的扩展。 实际上,这意味着从Object.class到Custom.class的最新实现扩展Object.class只能做一个层次结构。

但是null不是Object。

这意味着您不能在null上使用Dispatch机制,当它找到null引用时,它将引发NullPointerException。

这与Java无关,仅与分派机制的工作方式(多种或单一类型)无关

ps:在某些语言中,您可以创建从多个超类扩展的类。 Java不会这样做是为了避免出现钻石问题(您从方法名称相同的2个类扩展而来。编译器看起来它们做了不同的事情,并且不知道如何在两个类之间进行选择,因此它会自爆)。我听说在Java 8中您现在可以再次遇到该问题:)

JAVA支持动态调度 ,不过就是“ 运行时聚合 ”。

代码中的异常原因:

  • 正如其他人指出的那样,第一个代码不起作用,因为您正在对“ NULL”调用“ equals”方法
  • 您必须像下面这样声明“ foo”: String foo = null ;
  • 请参见此处,“ foo ”是引用类型为“ String ”的变量,但它引用的是“ null”而不是“ String”对象。 但是,由于“ foo ”是一个字符串类型的编译器,因此您可以在其上调用“ equals ”方法。 它没有给出编译时错误
  • 但是,当您运行代码并且如果“ foo ”仍然为NULL时,JVM将尝试在空对象上调用“ equals ”。 因此它吐出“ NULL POINTER EXCEPTION

可能的解决方案:

您可以使用以下解决方案之一,也可以同时使用这两种解决方案。

  • 像这样初始化“ fooString foo = new String();

  • 进行NULL检查

      if(foo!=null) { if(foo.equals("Constant")) { System.out.println("TRUE"); } } else { System.out.println("NULL"); } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM