Was ist der beste Weg, um zu wissen, ob alle Variablen in einer Klasse null sind?

Lesezeit: 5 Minuten

Benutzeravatar von th3an0maly
th3an0maly

Dies würde bedeuten, dass die Klasse initialisiert wurde, aber die Variablen nicht gesetzt wurden.

Eine Beispielklasse:

public class User {

    String id = null;
    String name = null;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Die tatsächliche Klasse ist riesig, die ich lieber nicht überprüfen möchte if(xyz == null) für jede der Variablen.

  • if(id == null) ist der Beste Methode.

    – KV Prajapati

    11. September 2012 um 3:13 Uhr


  • Referenzfelder werden auf ihren Standardwert initialisiert, nullin Ermangelung eines expliziten Initialisierers.

    – obataku

    11. September 2012 um 3:21 Uhr

Benutzeravatar von Didier L
Didier L

Eine weitere nicht reflektierende Lösung für Java 8, in Anlehnung an die Antwort von paxdiabo, jedoch ohne Verwendung einer Reihe von ifwäre, alle Felder zu streamen und auf Nullheit zu prüfen:

return Stream.of(id, name)
        .allMatch(Objects::isNull);

Dies bleibt ziemlich einfach beizubehalten, während die Reflexion vermieden wird Hammer.

  • Gibt es eine Möglichkeit, die Feldwerte zu erhalten, z. B.: Stream.of (id, name), Nullfelder entfernen und eine Liste mit Werten von Nicht-Null-Feldern zurückgeben

    – Spülen S

    3. März 2018 um 13:31 Uhr

  • @Rinsen können Sie verwenden filter() aber das ist eine andere Frage und wurde wahrscheinlich schon auf SO gestellt.

    – Didier L

    3. März 2018 um 13:39 Uhr

  • Danke für den Kommentar, das ist eine andere Frage, aber können Sie mir bitte mitteilen, wie das geht, da ich mit einem Problem feststecke und keine effiziente Lösung finden kann. Vielen Dank im Voraus

    – Spülen S

    3. März 2018 um 14:32 Uhr

Benutzeravatar von arshajii
arshajii

Versuchen Sie so etwas:

public boolean checkNull() throws IllegalAccessException {
    for (Field f : getClass().getDeclaredFields())
        if (f.get(this) != null)
            return false;
    return true;            
}

Obwohl es wahrscheinlich besser wäre, jede Variable zu überprüfen, wenn überhaupt möglich.

  • Leistungsmäßig liegt dieser weit hinter dem zurück if(variable==null) Methode?

    – th3an0maly

    12. September 2012 um 10:07 Uhr

  • Ja, es wird wahrscheinlich viel länger dauern als if (var == null).

    – arshajii

    12. September 2012 um 11:00 Uhr

  • @Yar, damit dies für private Felder funktioniert, sollten Sie f.setAccessible(true) ausführen.

    – Jawa

    22. März 2018 um 18:30 Uhr


  • Die Verwendung von Reflektion ist ziemlich langsam, verbirgt viel von dem, was tatsächlich getan wird, und allgemeiner gesagt, kann es mühsam sein, umzugestalten (ein Feld kann von Ihrer IDE als unbenutzt markiert werden, wenn es tatsächlich über Reflektion erfolgt :/ und Sie werden weiß nie, dass es tatsächlich verwendet wurde, es sei denn, Sie haben gute Tests oder Sie führen Ihre App aus.) Dies verbietet natürlich nicht die Verwendung von Reflektion, aber wenn Sie eine andere Option verwenden können, tun Sie es

    – minioim

    8. August 2019 um 13:03 Uhr


  • Es wird nie zu viel gesagt, dass Sie etwas hinzufügen müssen f.setAccessible(true) um IllegalAccessException auf privaten Feldern zu vermeiden.

    – Ara Kokeba

    21. November 2019 um 20:03 Uhr


Benutzeravatar von Martin Tarjányi
Martin Tarjanyi

Dies kann ziemlich einfach mit einem generierten Lombok erfolgen equals und eine Statik EMPTY Objekt:

import lombok.Data;

public class EmptyCheck {
    public static void main(String[] args) {
        User user1 = new User();

        User user2 = new User();
        user2.setName("name");

        System.out.println(user1.isEmpty()); // prints true
        System.out.println(user2.isEmpty()); // prints false
    }

    @Data
    public static class User {
        private static final User EMPTY = new User();

        private String id;
        private String name;
        private int age;

        public boolean isEmpty() {
            return this.equals(EMPTY);
        }
    }
}

Voraussetzungen:

  • Der Standardkonstruktor sollte nicht mit benutzerdefiniertem Verhalten implementiert werden, da dies zum Erstellen von verwendet wird EMPTY Objekt
  • Alle Felder der Klasse sollten implementiert sein equals (eingebaute Java-Typen sind normalerweise kein Problem, im Falle von benutzerdefinierten Typen können Sie Lombok verwenden)

Vorteile:

  • Keine Reflexion beteiligt
  • Da der Klasse neue Felder hinzugefügt werden, erfordert dies keine Wartung, da sie aufgrund von Lombok automatisch in der Klasse überprüft werden equals Implementierung
  • Im Gegensatz zu einigen anderen Antworten funktioniert dies nicht nur für Nullprüfungen, sondern auch für primitive Typen, die einen Nicht-Null-Standardwert haben (z. B. wenn das Feld ist int es prüft auf 0im Falle von boolean zum falseetc.)

  • Dadurch wird ein zusätzliches Objekt erstellt EMPTY zusammen mit jedem Objekt. Wird dies die Leistung beeinträchtigen?

    – Sp4Rx

    5. März 2019 um 0:34 Uhr

  • Leer ist hier ein statisches Feld, also sollte es kein Problem sein.

    – Martin Tarjanyi

    25. Juli 2019 um 17:13 Uhr

  • @MartinTarjányi, aber die Methode equals () in Java vergleicht Instanzen und nicht ihre Feldwerte. Sie müssen equals () und hashCode () überschreiben.

    – Tamim Attafi

    15. Januar 2020 um 6:09 Uhr

  • Deshalb habe ich die Lombok-Anmerkung verwendet

    – Martin Tarjanyi

    15. Januar 2020 um 6:10 Uhr

Wenn Sie dies für Komponententests benötigen, verwende ich einfach die hasNoNullFieldsOrProperties() Methode aus assertj

assertThat(myObj).hasNoNullFieldsOrProperties();

Wie wäre es mit Streams?

public boolean checkFieldsIsNull(Object instance, List<String> fieldNames) {

    return fieldNames.stream().allMatch(field -> {
        try {
            return Objects.isNull(instance.getClass().getDeclaredField(field).get(instance));
        } catch (IllegalAccessException | NoSuchFieldException e) {
            return true;//You can throw RuntimeException if need.
        }
    });
}

  • das ist nicht skalierbar.

    – saran3h

    30. Oktober 2021 um 6:15 Uhr

Benutzeravatar von paxdiablo
paxdiablo

“Beste” ist so ein subjektiver Begriff 🙂

Ich würde einfach die Methode verwenden, jede einzelne Variable zu überprüfen. Wenn Ihre Klasse bereits viele davon hat, ist die Zunahme in der Größe wird nicht so viel sein, wenn Sie so etwas tun:

public Boolean anyUnset() {
    if (  id == null) return true;
    if (name == null) return true;
    return false;
}

Vorausgesetzt, Sie halten alles in der gleichen Reihenfolge, werden Codeänderungen (und die automatische Überprüfung mit einem Skript, wenn Sie paranoid sind) relativ schmerzlos sein.

Alternativ (vorausgesetzt, es sind alles Strings) könnten Sie diese Werte grundsätzlich in eine Art Map einfügen (z. B. HashMap) und führen Sie einfach eine Liste der Schlüsselnamen für diese Liste. Auf diese Weise könnten Sie die Liste der Schlüssel durchlaufen und prüfen, ob die Werte richtig eingestellt sind.

  • das ist nicht skalierbar.

    – saran3h

    30. Oktober 2021 um 6:15 Uhr

Ich denke, dies ist eine Lösung, die Ihr Problem leicht löst: (true zurückgeben, wenn einer der Parameter nicht null ist)

  public boolean isUserEmpty(){ 
boolean isEmpty;
isEmpty =  isEmpty = Stream.of(id,
            name)
        .anyMatch(userParameter -> userParameter != null);

return isEmpty;}

Eine andere Lösung für dieselbe Aufgabe ist: (Sie können sie ändern in if(isEmpty==0) prüft, ob alle Parameter null sind.

public boolean isUserEmpty(){  
       long isEmpty;
            isEmpty = Stream.of(id,
                    name)
                    .filter(userParameter -> userParameter != null).count();
    
          return  isEmpty > 0

    }

1436160cookie-checkWas ist der beste Weg, um zu wissen, ob alle Variablen in einer Klasse null sind?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy