Améliorer le code Intellij d'inspection pour peut produire des avertissements NullPointerException

Rishi Dua:

J'ai une classe avec une hasFieldfonction qui vérifie si un champ est présent et non nul, et d' une getFieldfonction qui retourne la valeur du champ (ou nuls si non présent).

Dans mon code quand je l' appelle getFieldjuste après vérification hasField, je sais que getField ne va pas retourner null, mais l'Inspection IDE ( Conditions constantes et exceptions ) ne sait pas. Je reçois un tas de méthode method namepeut produire unNullPointerException

J'essaie de trouver un moyen propre à faire cet avertissement disparaître.

contournements

Voici quelques solutions de contournement que je pouvais faire, mais je trouve tous ces aki:

  1. Surround getFieldavec Objects.requireNotnull, le code ne serait pas-op. Préférerais ne pas le faire car il rend le code un peu moins lisible.
  2. avertissements Suppress où je sais que cela est sans danger. Encore une fois ne préfère pas que cela va se passer à un tas d'endroits dans notre code.
  3. Ignorer les avertissements. Dans ce cas, nous pourrions manquer les avertissements legit juste parce que la section des avertissements sera trop bruyant.

solution idéale

Est-ce que je serai en mesure de mettre en place une certaine façon les avertissements de telle sorte que si hasFieldest vrai, getFieldrenverra une non nulle? J'ai regardé dans les annotations JetBrains contrat , mais faire ce que je veux ici semble être au - delà de ce qui est pris en charge avec @Contract

Exemple de code

Voici un exemple de code de travail minimum qui démontre la question:

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; }
}

Je reçois l'avertissement suivant

Invocation méthode equalspeut produireNullPointerException

Je idéalement veux être en mesure de dire IDE getSample n'est pas nulle quand hasSample est vrai.

Tagir Valeev:

Divulgation Je suis développeur IntelliJ IDEA responsable de ce sous - système


Non, il est impossible maintenant. Il y a pas de meilleure solution que des solutions de contournement possibles que vous avez inscrits, en supposant que vous ne pouvez pas changer l'API. La chose la plus proche que nous avons est le inline des méthodes très triviales. Cependant, il ne fonctionne que si:

  • Les méthodes comme hasSample()et getSample()sont appelés de la même classe
  • Les méthodes appelées ne peuvent pas être surchargée (/ privé / statique / finale déclarée en classe finale)

Par exemple, cette fonctionnalité fonctionne dans le code suivant:

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";
  }
}

Pour l'instant, je ne peux que suggérer Remanier API pour Optional comme celui-ci:

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); }
}

Je suppose que tu aimes

Origine http://10.200.1.11:23101/article/api/json?id=478660&siteId=1
conseillé
Classement