【问题标题】:How to tell IDEA/Studio that the null check has been done?如何告诉 IDEA/Studio 已完成空值检查?
【发布时间】:2026-01-10 07:35:01
【问题描述】:

我正在使用 Android Studio/IntelliJ IDEA 进行开发。

我已启用名为“恒定条件和异常”的检查检查,如果我面临 NPE 风险,则会显示警告,例如:

String foo = foo.bar(); // Foo#bar() is @nullable
if (foo.contains("bar")) { // I'm living dangerously
    ...
}

我的代码中有以下内容:

String encoding = contentEncoding == null ? null : contentEncoding.getValue();
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
    inputStream = new GZIPInputStream(entity.getContent());
} else {
    inputStream = entity.getContent();
}

这里是TextUtils#isEmpty(String)的源代码:

/**
 * Returns true if the string is null or 0-length.
 * @param str the string to be examined
 * @return true if str is null or zero length
 */
public static boolean isEmpty(CharSequence str) {
    if (str == null || str.length() == 0)
        return true;
    else
        return false;
}

我不会冒任何 NPE 的风险,因为 TextUtils#isEmpty(String) 将返回 true 到 null 指针。

但是我仍然收到Method invocation 'encoding.equalsIgnoreCase("gzip")' may produce 'java.lang.NullPointerException' 的小警告,这可能很烦人。

如果已经进行了空值检查,是否可以使该检查更智能并忽略 NPE 警告?

【问题讨论】:

  • 您可以通过输入"gzip".equalsIgnoreCase(encoding) 来规避此问题。
  • 你说的没错,但并不总是String#equals。例如foo.contains(bar),两者都是指针:它可以警告 foo 可以为空,而空检查已经由 TextUtils#isEmpty 完成

标签: intellij-idea android-studio


【解决方案1】:

您可以查看 Peter Gromov 在其answer 中提到的链接。

创建了一些类似于您的设置的简单类:

一个方法用@Nullable注解的类:

TextUtil 类及其 isEmpty 方法:

最后是调用TextUtil#isEmpty的主类:

现在,如果您输入 File -> Settings... 并转到 Inspections ->Constant conditions & exceptions 部分,您可以更改 Configure Assert/Check Methods 以适应您的 isEmpty 方法:

新增IsNull校验方法:

输入TextUtil类,isEmpty方法和CharSequence参数:

这给出了这个Assert/Check Method Configuration 窗口:

再次按Ok,然后再按Ok 返回编辑器视图,您会看到检查消失了:

您实际上是在告诉 IntelliJ isEmpty 方法正在对 str 参数进行空检查。

【讨论】:

  • 哇。感谢您为这个答案付出的努力。太棒了!
  • 似乎至少在 Android Studio 1.2.2 中没有这样的选项(配置断言/检查方法)
  • @maba 你知道在上一个 Android Studio 中是怎么做的吗?
  • @tse 不,我不知道。我只使用 vanilla IntelliJ Ultimate Edition,而不是 Android Studio。
【解决方案2】:

您可以使用//noinspection ConstantConditions 来删除以下行的 NPE 警告,如下所示:

String encoding = contentEncoding == null ? null : contentEncoding.getValue();

//noinspection ConstantConditions
if (!TextUtils.isEmpty(encoding) && encoding.equalsIgnoreCase("gzip")) {
    inputStream = new GZIPInputStream(entity.getContent());
} else {
    inputStream = entity.getContent();
}

【讨论】:

    【解决方案3】:

    你可以使用@SuppressWarnings("ConstantConditions")注解。

    @SuppressWarnings("ConstantConditions")
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int indexViewType) {
        if (inflater == null) {
            inflater = LayoutInflater.from(parent.getContext());
        }
        ItemViewProvider provider = getProviderByIndex(indexViewType);
        provider.adapter = MultiTypeAdapter.this;
        return provider.onCreateViewHolder(inflater, parent);
    }
    

    【讨论】:

    • 不要在像这样的大量代码上抑制它:1)没有办法知道你实际上在抑制什么(可以provider为空,或parent,或@ 987654325@, ...?); 2) 它禁用对该范围内任何未来代码的检查(如果添加到此方法,即使是显式的((Object) null).toString(); 也不会警告空访问)
    【解决方案4】:
    1. 选择“TextUtils.isEmpty”。
    2. 右键单击 -> 显示上下文操作 -> 添加方法协定。
    3. 输入“null -> true”。
    4. 保存配置 xml。

    详情请查看here

    【讨论】:

      【解决方案5】:

      有关 IDEA 12,请参阅 http://www.jetbrains.com/idea/webhelp/configuring-check-assert-methods.html。 在 IDEA 13 EAP 中,可以添加方法契约:http://youtrack.jetbrains.com/issue/IDEA-93372

      【讨论】:

        【解决方案6】:

        不幸的是,标记为“正确答案”的解决方案已过时。但我找到了适合我的解决方案。

        新版本的 IDE 可以正确使用静态方法。因此,问题中的示例将不再发出警告。

        TextUtils#isEmpty(String);
        
        public static boolean isEmpty(CharSequence str) {
            // your checks
        }
        

        【讨论】:

        • 不幸的是,它会引发 android.text.TextUtils.isEmpty(String) 的警告
        最近更新 更多