【问题标题】:Null Pointer Exceptions in JavaJava 中的空指针异常
【发布时间】:2014-03-28 17:08:34
【问题描述】:

我了解尝试将 null 的 Object 的值与某物进行比较会导致 NullPointerException,例如,

String bob;
if(bob.equals("blahblahblah")){do_something();}

并且像这样使用嵌套检查是个好主意:

if(!bob.equals(null)){
    if bob.equals("blah blah blah"){
      do_something();
    }
}

但是如果我还没有给 bob 任何值,当我运行上面说 bob 尚未初始化时,我会收到一个错误 - 因为我将 bob 与 null 进行比较,所以我应该能够在没有问题,不应该吗?

谢谢。

【问题讨论】:

  • 您可以将 bob 与 null 进行比较是对的,但在这种情况下您将使用 == 运算符。对于字符串比较(在非空值上,意味着在空检查之后),您使用 .equals 方法。它不是引发异常的比较,而是对 null 对象 (bob) 上的 .equals 方法的调用。
  • 有什么区别?
  • @JonK Java 不是 C。在 Java 中,变量要么由用户/程序员初始化,要么具有默认值(false 用于布尔值,0 用于数值,null 用于引用) .如果变量不会被初始化并尝试使用,代码将无法编译。 BTW 只有类字段由编译器设置为具有默认值,局部变量(方法中声明的变量需要由用户/程序员初始化)。
  • @JonK 您评论中最有问题的句子是“JVM 分配给该变量的内存保留了它在 JVM 为变量抓取它之前所持有的任何内容”。例如,您说的是int i; /*some time passes*/ i=42; 在这种情况下i=42 之前的i 的内存实际上无法重置,因此它可以是任何一组位,但我们无法检查它,因为Java 明确要求在可以使用之前对其进行初始化(如jls-4.12.5 所述)。

标签: java nullpointerexception null initialization


【解决方案1】:

如果 bob 为 null 你不能做 bob.equals - 你需要检查

if (bob != null)

喜欢这个

if (bob != null) {
    if (bob.equals("blah blah blah")){

          do_something();
    }
}

一个很好的解决方法是

if ("blah blah blah".equals(bob)) {

}

【讨论】:

    【解决方案2】:
    !bob.equals(null)
    

    你试图在一个空对象上调用一个方法,因此你会得到错误。试试这个:

    bob != null
    

    【讨论】:

      【解决方案3】:

      想象写作

      null.equals(null)
      

      您希望它起作用吗?出于同样的原因,这不起作用。如前所述,您可以为此使用参考比较 (==),因为只有 1 个空值。

      【讨论】:

        【解决方案4】:

        正如 Shreyos 所指出的,您永远不会初始化 bob,因此您会得到 NPE。您可以使用Yoda Conditions 来防范这种情况:

        if("blahblahblah".equals(bob)){do_something();}

        您的字符串文字永远不能为空,因此equals() 比较将在bob 实际上为空时返回false。许多人嘲笑和开玩笑说使用这些技术,但在很多情况下它们很方便。

        【讨论】:

          【解决方案5】:

          您的bobnull,您不能调用equal() 或者将您的程序更改为

          if(bob != null){
              if bob.equals("blah blah blah"){
                do_something();
              }
          }
          

          String bob = new String("some string");一样初始化bob

          【讨论】:

          • 我不知道这个初始化的关键字。那是Java吗?
          • Java 关键字列表中没有看到已初始化:docs.oracle.com/javase/tutorial/java/nutsandbolts/…
          • 这与拼写无关。 Java 中没有“initialize”或“initialized”关键字。是 Scala 还是 Groovy 还是什么?
          • 哦。删除代码降价以进行初始化,这将消除任何潜在的混乱。我明白你在说什么。
          • 哦,对不起,我不是要初始化一个关键字,我只是想说初始化其中的一些值。
          【解决方案6】:

          你的问题是这样的:

          if(!bob.equals(null)){
              if bob.equals("blah blah blah"){
                do_something();
              }
          }
          

          假设你用 String bob; 声明了这个,编译器将默认为 String bob = null;

          null 本身就是一个指针(引用)。方法String.equals() 是String 类中引用的方法。由于您没有创建String 类型的对象,因此该类不存在,因此该方法也不存在。

          如果您要测试某个内容是否为 null(就像您最终编写生产代码时所做的那样),您将像这样使用等于运算符:

          if( null != bob ){ //operations on bob }

          额外细节:

          现在初始化是这样的,当你说这样的话:

          String bob = "foo";
          

          编译器实际上会写类似String bob = new String(foo);的东西

          这应该告诉你初始化意味着对象创建。

          我说“类似”是因为以下也是可能的:

          String bob = "foo" + "bar";
          

          编译器会写

          String bob = new StringBuilder("foo").append("bar").toString();
          

          【讨论】:

            猜你喜欢
            • 2011-01-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-03-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多