1308 Stimmen

Welche @NotNull-Java-Annotation sollte ich verwenden?

Ich möchte meinen Code lesbarer machen und Tools wie IDE-Code-Inspektion und/oder statische Code-Analyse (FindBugs und Sonar) verwenden, um NullPointerExceptions zu vermeiden. Viele der Tools scheinen inkompatibel mit den anderen zu sein. @NotNull / @NonNull / @Nonnull Annotation und die Auflistung aller von ihnen in meinem Code wäre schrecklich zu lesen. Irgendwelche Vorschläge, welche die "beste" ist? Hier ist die Liste der gleichwertigen Annotationen, die ich gefunden habe:

8voto

Cristan Punkte 8980

JSpecify ist jetzt der richtige Weg. In der Tat: ihre Präsentation verweist aktiv auf genau diese Frage und gibt an, dass es ihr Ziel ist, darauf endlich eine gute Antwort zu finden.

Sie hat wichtige Teilnehmer wie Android, Guava und Kotlin.

7voto

Werner Keil Punkte 117

Leider, JSR 308 fügt nicht mehr Werte hinzu als dieser projektspezifische Nicht-Null-Vorschlag hier

Java 8 wird nicht mit einem einzigen Standardkommentar oder einer eigenen Checker Rahmen. Ähnlich wie bei Find-bugs oder JSR 305 Dieser JSR wird von einer kleinen Gruppe von meist akademischen Teams schlecht gepflegt.

Keine kommerzielle Macht dahinter, daher JSR 308 Startet EDR 3 (Frühzeitige Überprüfung des Entwurfs unter JCP ) JETZT, während Java 8 soll in weniger als 6 Monaten ausgeliefert werden:-O Ähnlich wie 310 btw. aber im Gegensatz zu 308 Oracle hat den Gründern die Verantwortung dafür entzogen, um den Schaden für die Java-Plattform zu minimieren.

Jedes Projekt, jeder Anbieter und jede akademische Klasse, wie die, die hinter dem Checker Framework y JSR 308 erstellt eine eigene, proprietäre Checker-Anmerkung.

Die Inkompatibilität des Quellcodes auf Jahre hinaus, bis ein paar populäre Kompromisse gefunden und vielleicht ergänzt werden können Java 9 o 10 oder über Frameworks wie Apache Commons o Google Guava ;-)

7voto

noamtm Punkte 11449

Hier gibt es bereits zu viele Antworten, aber a) wir haben 2019 und es gibt noch keinen "Standard". Nullable und (b) keine andere Antwort verweist auf Kotlin.

Der Verweis auf Kotlin ist wichtig, denn Kotlin ist zu 100% interoperabel mit Java und verfügt über eine zentrale Null Safety Funktion. Beim Aufruf von Java-Bibliotheken können diese Annotationen genutzt werden, um Kotlin-Tools mitzuteilen, ob eine Java-API akzeptieren oder zurückgeben kann null .

Soweit ich weiß, ist die einzige Nullable mit Kotlin kompatible Pakete sind org.jetbrains.annotations y android.support.annotation (jetzt androidx.annotation ). Letzteres ist nur mit Android kompatibel und kann daher nicht in Nicht-Android-JVM/Java/Kotlin-Projekten verwendet werden. Das JetBrains-Paket funktioniert jedoch überall.

Wenn Sie also Java-Pakete entwickeln, die auch in Android und Kotlin funktionieren sollen (und von Android Studio und IntelliJ unterstützt werden), ist das JetBrains-Paket wahrscheinlich die beste Wahl.

Maven:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations-java5</artifactId>
    <version>15.0</version>
</dependency>

Gradle:

implementation 'org.jetbrains:annotations-java5:15.0'

7voto

Shubham Chaudhary Punkte 41926

Android

Diese Antwort ist Android-spezifisch. Android hat ein Unterstützungspaket namens support-annotations . Dies bietet Dutzende de Android-spezifisch Anmerkungen und bietet außerdem die Üblichen wie NonNull , Nullable usw.

Zum Hinzufügen Support-Anmerkungen Paket, fügen Sie die folgende Abhängigkeit in Ihrer build.gradle hinzu:

compile 'com.android.support:support-annotations:23.1.1'

und dann verwenden:

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

6voto

Mozart Brocchini Punkte 332

In Java 8 gibt es eine andere Möglichkeit, dies zu tun. Ich tue 2 Dinge, um zu erreichen, was ich brauchte:

  1. Explizite Darstellung von löschbaren Feldern mit Typen durch Umhüllung löschbarer Felder mit java.util.Optional
  2. Überprüfung, dass alle nicht löschbaren Felder zur Erstellungszeit nicht null sind, mit java.util.Objects.requireNonNull

Ejemplo:

Edit: Ignorieren Sie dieses 1. Beispiel, ich lasse es hier nur als Kontext der Diskussion in den Kommentaren. Überspringen Sie die empfohlene Option nach diesem (2. Codeblock).

    import static java.util.Objects.requireNonNull;

    public class Role {

      private final UUID guid;
      private final String domain;
      private final String name;
      private final Optional<String> description;

      public Role(UUID guid, String domain, String name, Optional<String> description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = requireNonNull(description);
      }
   }

Meine Frage ist also, brauchen wir überhaupt zu annotieren, wenn Sie Java 8 verwenden?

Edit: Ich habe später herausgefunden, dass einige die Verwendung von Optional in Argumenten, hier gibt es eine gute Diskussion mit Pro und Kontra Warum sollte das Optional von Java 8 nicht in Argumenten verwendet werden?

Empfohlene Option, da es nicht die beste Praxis ist, Optional in Argumenten zu verwenden, benötigen wir 2 Konstruktoren:

public class Role {

      // Required fields, will not be null (unless using reflection) 
      private final UUID guid;
      private final String domain;
      private final String name;
      // Optional field, not null but can be empty
      private final Optional<String> description;

  //Non null description
  public Role(UUID guid, String domain, String name, String description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);

        // description will never be null
        requireNonNull(description);

        // but wrapped with an Optional
        this.description = Optional.of(description);
      }

  // Null description is assigned to Optional.empty
  public Role(UUID guid, String domain, String name) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = Optional.empty();
      }
  //Note that this accessor is not a getter.
  //I decided not to use the "get" suffix to distinguish from "normal" getters 
  public Optional<String> description(){ return description;} 
 }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X