如何检查变量是否在Java中初始化?

Rya*_* H. 0 java

我正在搞乱一些代码并遇到一个空指针异常,这是一个未初始化的变量的结果.所以我只是想知道:有没有办法在尝试处理它之前验证一个对象实际存在,从而避免这样的错误?

Ste*_*n C 5

有三种情况:

  1. 如果变量是方法参数或catch变量,则保证初始化,因为Java语义会处理它

  2. 如果变量是局部变量,则保证初始化,因为编译器不允许您访问未明确赋值的局部变量.

  3. 如果变量是class(static)或实例变量,那么它将在声明中显式初始化,或者默认初始化为1.

在第三种情况下,默认初始值null用于引用类型,零用于数字类型或false用于boolean.在使用变量之前,始终可以测试变量是否具有该(已知)值.

但是,您不知道它是否具有该值,因为它未初始化,或者是否已明确分配该值.例如:

  if (object != null) {
    // Object has been initialized
  } else {
    // ...
  }
Run Code Online (Sandbox Code Playgroud)

在这种else情况下,我们不确定变量是否已初始化.它可以被明确初始化为null.它本来可以初始化为其他东西,然后null分配给它.

但是,您可能只想知道变量是否null存在.您可以确定使用== null测试,如上所述......或以其他方式; 例如,使用三元运算符或Objects.nonNull(Java 8及更高版本).


1 - 类变量有一些边缘情况,其中使用初始化程序声明的变量仍可在默认初始化状态下观察到.


由于多种原因,从NPE中捕获和恢复的建议是一个坏主意.一个原因是很难确定导致任何给定NPE的原因.(因为它是您关注的特定变量......或其他什么?例如:

   SomeClass sc = // may be null
   try {
       sc.someMethod();
   } catch (NullPointerException ex) {
       // We don't know for sure if 'sc' was null, or if the NPE
       // happened within the `someMethod()` call.
   }
Run Code Online (Sandbox Code Playgroud)

简而言之,这种方法容易产生误导性结果.


处理未初始化变量问题的其他两种方法:

  • 使用@NotNull注释和静态代码分析器.
  • 使用Optional.

然而,在现实世界的Java中,这些都不是"防弹的".