J'ai une classe avec une hasField
fonction qui vérifie si un champ est présent et non nul, et d' une getField
fonction qui retourne la valeur du champ (ou nuls si non présent).
Dans mon code quand je l' appelle getField
juste 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 name
peut 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:
- Surround
getField
avecObjects.requireNotnull
, le code ne serait pas-op. Préférerais ne pas le faire car il rend le code un peu moins lisible. - 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.
- 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 hasField
est vrai, getField
renverra 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
equals
peut produireNullPointerException
Je idéalement veux être en mesure de dire IDE getSample n'est pas nulle quand hasSample est vrai.
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()
etgetSample()
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); }
}