NullPointerExceptionが警告を生成することためのIntelliJコードインスペクションを改善

リシドゥア:

私はクラス有するhasFieldフィールドが存在しないヌル、およびある場合にチェックその機能getFieldフィールド(またはnullでない場合に存在する)の値を返す関数。

私は呼んで私のコードではgetField、右のチェックの後hasField、私はのgetFieldがnullを返すために起こっていないことを知っているが、IDE検査(一定条件と例外は)それを知りません。私はこの方法の束が取得method name生じることNullPointerException

私は、この警告が離れて行くようにするきれいな方法を見つけようとしています。

回避策

ここで私は何ができるいくつかの回避策がありますが、私はこれらのハックのすべてを見つけます:

  1. サラウンドgetFieldとはObjects.requireNotnull、コードには、オペアンプないだろう。それはコードが少し読みにくくなりますようことをやっていない好みますか。
  2. 私はこれが安全である知っ抑制の警告。ここでも、これは私たちのコード内の場所の束で起こるために起こっているとして好ましいものではありません。
  3. 警告を無視します。警告セクションがあまりにもうるさいだろうという理由だけで、このケースでは、合法的な警告を見逃す可能性があります。

理想的なソリューション

私は何とか場合ように警告を設定することができるだろうhasField真である場合、getFieldnull以外を返すのだろうか?私は、に見えたJetBrainsの契約注釈が、私はここで何をしたいことは@Contractでサポートされている以上のようです

コードサンプル

ここでは、問題を実証最小作業コードサンプルです:

import javax.annotation.Nullable;

public class Hello {

  private Hello(){}
  public static void main(String[] args) {
    TestClass test1 = new TestClass(null);
    if (test1.hasSample()) {
      System.out.println(test1.getSample().equals("abc"));
    }
 }
}

class TestClass {
  private final String sample;

  TestClass(String field) { this.sample = field; }

  boolean hasSample() { return sample != null; }

  @Nullable public String getSample() { return sample; }
}

私は次の警告を取得します

メソッドの呼び出しをequals生成することがNullPointerException

私は、理想的hasSampleがtrueの場合getSampleがnullでないことをIDEに伝えることができるようにしたいと思います。

Tagir Valeev:

開示私はこのサブシステムを担当するのIntelliJ IDEAの開発者です


いいえ、それは今はできません。すでに記載された回避策よりも良いソリューションを使用すると、APIを変更することはできませんと仮定して、ありません。我々が持っている最も近いものは、非常に些細なメソッドのインライン化です。しかし、それは場合にのみ動作します。

  • 以下のような方法hasSample()とはgetSample()同じクラスから呼び出され
  • 呼び出されたメソッドをオーバーライドすることはできません(プライベート/静的/最後の/は、最終的なクラスで宣言)

例えば、この機能は、次のコードで動作します。

final class TestClass { // if final is removed, the warning will appear again
  private final String sample;

  TestClass(String field) { this.sample = field; }

  boolean hasSample() { return sample != null; }

  @Nullable
  public String getSample() { return sample; }

  @Override
  public String toString() {
    if (hasSample()) {
      return "TestClass: "+getSample().trim(); // no warning on trim() invocation here
    }
    return "TestClass";
  }
}

今のところ、私はこのようなOptionalsにあなたのAPIをリファクタリング提案することができます:

import java.util.Optional;

public class Hello {

  private Hello(){}
  public static void main(String[] args) {
    TestClass test1 = new TestClass(null);
    test1.getSample().ifPresent(s -> System.out.println(s.equals("abc")));
    // or fancier: test1.getSample().map("abc"::equals).ifPresent(System.out::println);
  }
}

final class TestClass {
  private final String sample;

  TestClass(String field) { this.sample = field; }

  public Optional<String> getSample() { return Optional.ofNullable(sample); }
}

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=478659&siteId=1