簡體   English   中英

Google-guava checkNotNull 和 IntelliJ IDEA 的“可能會產生 java.lang.NullPointerException”

[英]Google-guava checkNotNull and IntelliJ IDEA's “may produce java.lang.NullPointerException”

有沒有辦法抑制這個警告:

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,我知道這個警告是不必要的,但是我想在這里壓制它並避免關閉檢查。

通過@Contract注釋和外部注釋功能的組合,您現在可以注釋Preconditions方法,以便 IntelliJ 將正確的 static 分析應用於對這些方法的調用。

假設我們有這個例子

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)
  • 將 cursor 放在方法名稱上,然后按 Alt - Enter以彈出意圖彈出窗口。
  • Select“添加方法合同”。
  • 使用合同文本false -> fail
  • 出現提示時,提供外部注釋文件的位置。

現在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>

也可以看看

JetBrains Yourtrack 中存在添加此類功能的老問題 幾年前我投票支持它,但我沒有看到任何活動。 如果每個人都投票支持它,那么我們可能會很幸運。

澄清問題包括添加功能,以便您可以將方法標記為執行某種類型的 null 檢查。 如果發生這種情況,那么您可以為 Preconditions 方法編寫自己的包裝器並對其進行注釋。

更新我厭倦了等待功能,所以我自己提交了一個補丁。 它在 12.1.1 版本 129.239 中可用。 要訪問配置:設置 > 檢查 > 可能的錯誤 > 常量條件和異常 > 配置斷言/檢查方法。

提取方法?

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

...

MyClass object = getMyClass();
Preconditions.checkNotNull(object);
merged.setName(object.getName());

您還可以從 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());

從 IntelliJ IDEA 14 開始,您無需擔心這一點。

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

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

早期的 IntelliJ IDEA 不知道如果 url 是 null,代碼執行甚至不會到達“startsWith”調用,因為它沒有查看 StringUtils.isEmpty 內部。 您當然可以通過自己查看 isEmpty 並添加合同“null -> true”來刪除 extractPrefix 中的那些黃色警告,但這太無聊了,這正是計算機的工作,而不是你,現在 IntelliJ IDEA 會自動完成。 查看字節和源代碼。

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

除了其他選擇,您可以嘗試-

通過使用 - 在方法級別抑制警告 -

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

或通過使用注釋來抑制語句級別的警告 -

//noinspection NullableProblems
someMethodCallProducingNullWarning(null);

但在這樣做之前 - 確保它不會真正產生 NPE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM