【问题标题】:Using StringUtils.isEmpty without losing compiler warnings about null pointers使用 StringUtils.isEmpty 而不会丢失关于空指针的编译器警告
【发布时间】:2014-07-26 05:42:39
【问题描述】:

我倾向于使用org.apache.commons.lang.StringUtils 类而不是通常的if (myString == null || myString.equals("")),并使用if (StringUtils.isEmpty(myString))

但是,这 - 至少我这样做的方式 - 有一个巨大的缺点:因为 FindBugs - 或编译器警告机制,f。前任。来自 Eclipse - 将不再看到显式的 null 检查,它将不再将 myString 视为可能为 null,因此它将不再发出有关其潜在(或确定)空指针的警告,并且这些警告非常有用在我看来。

示例(添加):

import org.apache.commons.lang.StringUtils;

public class TestWarning
{
    void testWarning(String myString)
    {
        //if (myString == null || myString.equals("")) // With this, the last line shows the warning.
        if (StringUtils.isEmpty(myString)) // With this, no warning.
        {
            // Anything.
        }
        int x = myString.length(); // Warning is here: "Potential null pointer access: The variable myString may be null at this location"
    }
}

所以我只是想确保没有办法消除或最小化这个缺点,以便人们可以使用StringUtils.isEmpty 并仍然收到空指针警告。也许像@Nullcheck 这样的注释要添加到isEmpty 方法或其他东西?

添加:例如,创建像@Nullcheck 这样的自定义注释是否可行,将其添加到isEmpty 的arg 就像public static boolean isEmpty(@Nullcheck String str) 只是为了表明该方法对该arg 进行空检查, 并让编译器警告机制或 FindBugs 将 if (StringUtils.isEmpty(myString)) 视为显式空检查?

【问题讨论】:

  • StringUtils.isEmpty() 处理 null 那么为什么 FindBugs 应该引发“可能为 null”的警告呢?我在这里没有收到您的问题...
  • 您担心什么空指针警告?你能再解释一下吗?您是否想要在尝试检查以下内容时可能会引发 NPE 的警告:StringUtils.isEmpty(null)?因为如果是这种情况,那么您不必担心它,因为 StringUtils.isEmpty() 会自行处理 null,因此 FindBugs 不会因不必要的警告而困扰您。 Read the docs 了解更多信息。
  • 我不担心isEmpty 中的空指针;只是如果我做if (myString == null) 和下面的一些行 - 在if 之外 - 我为前做。 myString.length() 我将收到一个关于myString.length() 潜在空指针的编译器警告。如果我不使用if (myString == null) 而不是if (StringUtils.isEmpty(myString)),我将不会收到该警告
  • 编译器甚至像 FindBugs 这样的工具都有限制,而您刚刚找到了一个。基本上这就是为什么你作为程序员需要使用你的大脑:)
  • 对。但这适用于许多旨在最大程度减少错误的结构和工具 - 意外或由于无知 - 我有点喜欢这样 ;)

标签: java compiler-warnings apache-commons findbugs null-pointer


【解决方案1】:

您是否收到潜在的空指针警告实际上取决于静态代码分析器的性能。从逻辑上讲,如果你使用

if (myString == null || myString.equals(""))

您的代码期望 myString 为空。但是,在下一行中,您取消引用 myString。静态代码分析器看到这两个事实,并创建一个空指针警告。

如果你使用

if (StringUtils.isEmpty(myString))

您的代码没有说明它是否期望 myString 为空。因此,静态代码分析器不会生成空指针警告。静态代码分析器当然可以选择生成空指针警告,但这会产生很多误报,因为它需要假设任何方法的输入都可能为空。

【讨论】:

  • 同意,这就是重点。所以我想知道是否可以注释isEmpty 签名以让编译器知道if (StringUtils.isEmpty(myString))if (myString == null) 一样对myString 进行空检查。我尝试了上面的 JSR-305 @Nullable 建议,但 @Nullable 似乎没有这样做。
【解决方案2】:

如果你用@Nullable注释myString,即

void testWarning(@Nullable String myString)

那么当你取消引用它时,至少 eclipse 会报告一个警告。

我同意 FindBugs 也应该对此发出警告,但我也无法让它这样做。

【讨论】:

  • 这就是我在问题的第 10 条评论中尝试的示例;它在 Eclipse 中不起作用,但也许这不是您的意思。我在那里发布的代码并没有真正的可读性,所以我在这里再试一次。应该可以将它粘贴到 IDE 中并让它格式化代码。 import javax.annotation.Nullable; public class TestWarning { void testWarning(String myString) { if (isEmpty(myString)) { /* Anything. */ } int x = myString.length(); /* No nullness warning */ } public static boolean isEmpty(@Nullable String str) { return str == null || str.length() == 0; }}
  • 如果您的意思是我应该将@Nullable 放在调用代码中(在我的示例中为testWarning 方法),那么这不是我要说的。如果我这样做,是我说myString 可能为空。我希望编译器从if (isEmpty(myString)) 推断myString 可能为空,就像它从if (myString == null) 推断一样。我希望做if (isEmpty(myString)) 和做if (myString == null) 对警告有相同的效果(即显示警告)。
  • 是的,我的意思是把 @Nullable 放在 testWarning 的参数上。当您说if (myString == null) 时,您是在告诉 eclipse/findbugs 您知道 myString 可能为空。如果该测试不存在,另一种提供相同信息的方法是将 myString 标记为 @Nullable。当你调用isEmpty 时,即使它的参数被标记为@Nullable,你也没有告诉它。它接受非空参数,但这并不意味着您认为 myString 可能为空。
  • 明白,谢谢。以这种方式使用@Nullable 将是一个合理的妥协;不如让编译器自己弄清楚myString 可以为空,就像它对if (myString == null) 所做的那样,但这可能是最接近的。
【解决方案3】:

Eclipse 代码分析还可以评估外部空注释(从 4.5.0 开始)。更多信息请访问https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    相关资源
    最近更新 更多