【问题标题】:Potential null pointer access潜在的空指针访问
【发布时间】:2013-05-17 06:31:30
【问题描述】:

我遇到了一个我目前还不清楚的奇怪情况:

当在 Eclipse 中启用可能的空指针访问警告时,我会收到如下警告(警告位于相应注释之前的行):

protected Item findItemByName(String itemName, Items items) {
    boolean isItemNameMissing = null == itemName || itemName.isEmpty();
    boolean isItemsMissing = null == items || null == items.getItems() || items.getItems().isEmpty();

    if (isItemNameMissing || isItemsMissing) {
        return null;
    }
    // potential null pointer access: the variable items might be null at this location
    for (Item item : items.getItems()) {
        // potential null pointer access: the variable itemName might be null at this location
        if (itemName.equals(item.getName())) {
            return item;
        }
    }

    return null;
}

如果我使用 Guava 的先决条件检查 null,也会发生同样的情况

Preconditions.checkArgument(argument != null, "argument must not be null");

我可以理解,在后一种情况下,用于检查 IllegalArgumentException 何时发生的流分析可能太困难/昂贵甚至不可能,我反过来也不明白编译器为什么会发出警告(如果我删除它们消失的检查)。

能否解释一下潜在的空指针访问是如何实现的,以及为什么在这两种情况下都会出现这种情况?或者至少给我指明方向。

同时我也看看是不是我自己发现了...

附录

我已经将其分解为案例的核心。给定以下类,警告仅显示在方法 sample2 中(正如评论再次指出的那样)。请注意,sample3 方法也不会触发警告。

public class PotentialNullPointerAccess {

    public void sample1(final String aString) {

        if (aString == null) {
            return;
        }

        System.out.println(aString.length());
    }

    public void sample2(final String aString) {

        boolean stringIsNull = null == aString;

        if (stringIsNull) {
            return;
        }

        // Potential null pointer access: The variable aString might be null at this location
        System.out.println(aString.length());

    }


    public void sample3(final String aString) {

        System.out.println(aString.length());
    }
}

【问题讨论】:

  • 代码的前 2 行似乎对读者不友好,IMO 你应该使用大括号对表达式进行分组
  • 您收到的确切警告是什么?为什么你认为它来自编译器,而不是来自Eclipse?
  • @T.J.Crowder:我不知何故将 compiler 也包含在了 Eclipse Java Compiler (ejc) 中。此外,正如我所写的那样,我收到的确切错误消息已在评论中说明(第一个字符是大写字母除外)。
  • @sanbhat:是的。 Fwiw,这是我发现的代码。如果涉及到设计缺陷/代码异味等问题,在这个小方法中会有几件事值得一提……
  • 你应该把它带到一个 Eclipse 论坛,甚至可以直接提交一个错误。

标签: java null guava compiler-warnings eclipse-jdt


【解决方案1】:

我认为 Ed Merks 在这个论坛帖子中以某种方式回答了这个问题:

http://www.eclipse.org/forums/index.php/t/278687/

据我了解,一旦您在前面的代码中假设变量可能是null,Eclipse 就会发出警告。您可以通过检查 null(相等或不相等)来做到这一点 - 但您必须将其作为变量分隔,而不仅仅是作为 if 的唯一表达式。

【讨论】:

    【解决方案2】:

    这可能不是警告的原因,但在这里你可以有一个空指针。

    for (Item item : items.getItems())
    {
        // potential null pointer access: the variable itemName might be null at this location
        if (itemName.equals(item.getName()))
        {
            return item;
        }
    }
    

    您迭代对象,但返回的对象可以为空。所以 item.getName() 会导致空指针异常。

    示例

     List<String> l = new ArrayList<String>();
     l.add("test");
     l.add(null);
     l.add("another string");
    
     if(l == null)   // <-- this is similar to the above check
        return;
    
     for(String s : l)
     {
         s.charAt(0);   //  <-- null pointer access on second item.
     }
    

    【讨论】:

    • 您可以将item.getName() 替换为任何常量,因此是明显的非空字符串,但警告会保留。
    • 这就是为什么我说这不是警告的原因,但仍然会导致空指针。
    • 啊,现在我明白你的意思了。但是首先,foreach 循环真的会产生null 吗?
    • 这取决于您在迭代器中传递的内容。我用一个例子更新了我的帖子来说明我的意思。当然 Eclipse 不会对此显示空指针警告,因此您必须自己处理它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多