避免"潜在的空指针访问"

时间:2015-01-29 09:37:11

标签: java nullpointerexception final

您认为这是实施以下问题时的最佳做法:

MyClass myVariable = null;
if ( ..condition 1.. ) {
  myVariable = new MyClass(1);
} else if ( ..condition 2.. ) {
  myVariable = new MyClass(2);
}

myVariable.execute();

哪种方法可以很好地解决警告?

  1. 完成else

    final MyClass myVariable;
    ....
    } else {
      // let's say this assert makes sense here
      Assert.fail("This should not happen");
    }
    
  2. 抛出RuntimeException

    final MyClass myVariable;
    ....
    } else {
      throw new RuntimeException("Some message, like <should not happen>");
    }
    
  3. 检查NPE

    final MyClass myVariable;
    ....
    if (myVariable != null) {
      myVariable.execute();
    }
    
  4. 其他想法?

  5. 提前致谢!

5 个答案:

答案 0 :(得分:1)

取决于条件1或条件2是否必须始终为真。 如果条件2与条件1完全相反,则可以将else if ( ..condition 2.. )替换为else并解决您的问题。

如果不是,并且条件1和条件2均为假的事实表明某些无效输入,我会抛出异常。

如果两个条件都为假的情况是有效的情况,我会在调用myVariable之前检查myVariable.execute()是否为空。

答案 1 :(得分:0)

以下情况更好。

final param;
if ( ..condition 1.. ) {
  param = 1;
} else if ( ..condition 2.. ) {
  param = 2;
} else {
   throw new IllegalArgumentException("no condition matches");
}

new MyClass(param).execute();

如果您的条件很简单,请尝试使用switch-case重写if-else链。这个比较好。

答案 2 :(得分:0)

我会做一个空检查,就像你的第三个例子。如果要实现的功能是侧面功能或可选功能,则可以在变量为空时忽略它。 当你有一个主要功能,并且用户等待响应时,你应该给用户发消息并让他再试一次。

答案 3 :(得分:0)

如果您始终可以初始化变量,请使用以if-else结尾的else

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...
else
    myClass = new MyClass(n);

myClass.execute();

如果您无法始终初始化变量,并且只想在初始化时使用该变量:

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...

if (myClass != null)
    myClass.execute();

如果您无法始终初始化您的变量,则需要:

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...
else
    throw new Exception(...);// or notify the user and exit

myClass.execute();

另一种方法是定义init()方法:

MyClass myClass = init(...);

// check if myClass is != null if init can return a null
myClass.execute();

MyClass init(...) {
    if (...)
        return new MyClass(1);
    else if (...)
        return new MyClass(2);
    else if (...)
        ...
    else
        return new MyClass(n);// or return null

简而言之,这取决于你的情况。

答案 4 :(得分:0)

  

您认为这是实施以下问题时的最佳做法

这取决于具体情况:

  • 这取决于检查condition 1condition 2的(深层)目的。

  • 这取决于对他们来说意味着什么都是假的:

    • 这是“正常”状况吗?

    • 是用户输入错误吗?

    • 调用此方法的代码中是编程错误吗?

    • 这段代码是编程错误吗?例如违反不变量?

    • 还有别的吗?

  • 这取决于您希望如何处理该案例。

根据这一点,您提出的任何替代方案都可能是适当的。


  

......你会说这是最好的做法......

对于像这样的事情,我不会使用“最佳实践”这个短语。即使我知道背景也不行。每当我在一个问题中听到“最佳实践”这个短语时,我就会觉得有人想要一个他们可以不假思索地应用的“千篇一律”解决方案。

我在这里推荐的唯一“最佳实践”是理解上下文,并选择最适合它的解决方案。

并且......“任何使警告消失的解决方案”都不是正确的方法。