36

有没有办法抑制这个警告:

MyClass object = null;

/*Some code that 'might' set this object but I know it will*/      


Preconditions.checkNotNull(object); 
//when "assert object != null" is used here no warning is shown

merged.setName(dRElement.getName());
//"May produce 'java.lang.NullPointerException'" warning here 

我正在使用 IntelliJ IDEA 10.5,我知道这个警告是不必要的,但是我想在这里压制它并避免关闭检查。

4

6 回答 6

32

通过@Contract注释和外部注释功能的组合,您现在可以注释Preconditions方法,以便 IntelliJ 将正确的静态分析应用于对这些方法的调用。

假设我们有这个例子

public void doSomething(Object someArg) {
    Preconditions.checkArgument(someArg != null);
    someArg.doSomethingElse();  //currently gives NPE warning

    if (someArg != null) {
        //no warning that this is always true
    }
}

在 IntelliJ 中(我使用的是 13):

  • 导航到Preconditions.checkArgument(boolean)
  • 将光标放在方法名称上,然后点击Alt-Enter以弹出意图弹出窗口。
  • 选择“添加方法合同”。
  • 使用合同文本false -> fail
  • 出现提示时,提供外部注释文件的位置。

现在 at 的警告someArg.doSomethingElse()消失了,IDEA 实际上会将if分支标记为始终为真!

其他合同文本:

  • Preconditions.checkArgument(boolean, String)应该false, _ -> fail
  • Preconditions.checkNotNull(Object, String)应该null, _ -> fail
  • 等等等等

这是我的完整annotations.xml文件Preconditions

<root>
    <item name='com.google.common.base.Preconditions T checkNotNull(T)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;null -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions T checkNotNull(T, java.lang.Object)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;null, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions T checkNotNull(T, java.lang.String, java.lang.Object...)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;null, _, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkArgument(boolean)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkArgument(boolean, java.lang.Object)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkArgument(boolean, java.lang.String, java.lang.Object...)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false, _, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkState(boolean)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkState(boolean, java.lang.Object)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
    <item name='com.google.common.base.Preconditions void checkState(boolean, java.lang.String, java.lang.Object...)'>
        <annotation name='org.jetbrains.annotations.Contract'>
            <val val="&quot;false, _, _ -&gt; fail&quot;"/>
        </annotation>
    </item>
</root>

也可以看看

于 2014-02-10T23:46:22.983 回答
15

JetBrains Yourtrack中存在添加此类功能的老问题。几年前我投票支持它,但我没有看到任何活动。如果每个人都投票支持它,那么我们可能会很幸运。

澄清问题包括添加功能,以便您可以将方法标记为执行某种类型的空检查。如果发生这种情况,那么您可以为 Preconditions 方法编写自己的包装器并对其进行注释。

更新 我厌倦了等待功能,所以我自己提交了一个补丁。它在 12.1.1 版本 129.239 中可用。要访问配置:设置 > 检查 > 可能的错误 > 常量条件和异常 > 配置断言/检查方法。

于 2011-07-07T14:49:33.217 回答
2

提取方法?

private MyClass getMyClass() {
    /* This always returns an instance of MyClass, never null. */      
}

...

MyClass object = getMyClass();
Preconditions.checkNotNull(object);
merged.setName(object.getName());
于 2011-07-06T15:27:03.180 回答
1

您还可以从 checkNotNull 方法分配返回值,该值非空:http ://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Preconditions.html# checkNotNull(T)

MyClass object = null;
object = Preconditions.checkNotNull(object); 
merged.setName(dRElement.getName());
于 2014-08-29T08:14:50.970 回答
1

从 IntelliJ IDEA 14 开始,您无需担心这一点。

@Nullable
String extractPrefix(@Nullable String url) {
    if (StringUtils.isEmpty(url)) return null;

    if (url.startsWith("jar://")) {
...

早期的 IntelliJ IDEA 不知道如果 url 为空,代码执行甚至不会到达“startsWith”调用,因为它没有查看 StringUtils.isEmpty 内部。您当然可以通过自己查看 isEmpty 并添加合同“null -> true”来删除 extractPrefix 中的那些黄色警告,但这太无聊了!这完全是计算机的工作,而不是你,现在 IntelliJ IDEA 会自动执行它,查看字节和源代码。

http://blog.jetbrains.com/idea/2014/10/automatic-notnullablecontract-inference-in-intellij-idea-14/

于 2014-11-27T14:47:40.223 回答
0

除了其他选项,您可以尝试-

通过使用 - 在方法级别抑制警告 -

@SuppressWarnings({"NullableProblems"})
public void someMethod(){
   ...
   ...
}

或通过使用注释来抑制语句级别的警告 -

//noinspection NullableProblems
someMethodCallProducingNullWarning(null);

但在这样做之前 - 确保它不会真正产生 NPE

于 2011-07-06T20:32:47.367 回答