Warum nullable Booleans doof sind ...

... erkennt man ganz gut, wenn ein Boolean zwingend true sein soll, abhängig davon ob einer von zwei anderen Boolean true ist.

Code:
setBooleanA ((getBooleanB() == null ? false : getBooleanB() || getBooleanC() == null ? false : getBooleanC) ? true : getBooleanA == null ? false : getBooleanA);

Ich habe aus den Methoden einfach mal Member-Methoden gemacht und die Namen vereinfacht, damit es etwas "übersichtlicher" wird.

Evtl. gibt es ja eine komaptere Schreibweise. Auf jeden Fall bleibe ich bei meiner Aussage: nullable Booleans sind doof!
 

thecain

Top Contributor
Ein Objekt kann nun mal null sein, das das doof findest ändert daran nichts...

Was ist eigentlich der Sinn hinter dem Thema?
 
Ein Boolean, der aus der Oberfläche ans Backend geht, hat genau zwei Zustände, true oder false, der User hat die Checkbox angehakt, oder eben nicht. Daher ist es meiner Meinung nach unsauber, dass überhaupt auf null geprüft werden muss, es sollte vom Frontend sicher gestellt sein, dass ein Boolean nicht null ist.

Ich habe den Code noch mal beispielhaft angepasst. Informationstransfer von einem Objekt zum anderen mit "sprechenderen" Namen.
Für mich wird das halt mit der Zeit unnötig unleserlich ...
Code:
einObjekt.setTollerBooleanName ((nochEinObjekt.getSuperDuperBoolean() == null ? false : nochEinObjekt.getSuperDuperBoolean() || nochEinObjekt.getAuchEinSuperBoolean() == null ? false : nochEinObjekt.getAuchEinSuperBoolean) ? true : nochEinObjekt.getTollerBooleanName == null ? false : nochEinObjekt.getTollerBooleanName);
 

Joose

Top Contributor
Ein Boolean, der aus der Oberfläche ans Backend geht, hat genau zwei Zustände, true oder false, der User hat die Checkbox angehakt, oder eben nicht.
Oder eben "null" dann wurde die Checkbox nie angefasst ;)

Für mich wird das halt mit der Zeit unnötig unleserlich ...
Wenn du die Klasse von "nochEinObjekt" erweitern kannst könntest du eine Methode schreiben welche dir ein primitives boolean zurückliefert statt einem Objekt.
Ansonsten richtig die Zeilenumbrüche setzen oder den Code auf mehrere Zeilen aufsplitten. Grundsätzlich sollte die Lesbarkeit wichtiger sein als das man so wenig Zeilen/Instruktionen wie möglich verwendet (Ausnahmen wie Performance mal ausgelassen)
 
Dann ist die Modellierung mittels eines Wahrheitswerts die falsche Wahl, und dreiwertige Logik über ein Boolean und null zu imitieren ist eine Unsitte. Sinnvoller ist es ein Enum mit 3 Werten zu verwenden.
Eben das! Wenn die Checkbox nicht angefasst wurde muss meiner Meinung nach fasle ans Backend gegeben werden.
Zumindest stelle ich mir so clean code vor.
 
Wenn du schon Clean Code erwähnst dann solltest du auch ernsthaft darüber reflektieren ob es "clean" ist mehr als drei ternäre Ausdrücke zu schachteln.
Das ist richtig. Fällt die null Prüfung weg, bleibt bei meinem Code nur eine ternäre Prüfung übrig. ;-)
Hatte ich ursprünglich auch ... bis zu den NullPointerExceptions.

Das bereitet mir an diesem konkreten Beispiel hatl Bauchschmerzen. Nun ist es leider so und hätte, wäre, wenn ist alles nice to have, allerdings sind bei uns nur noch zwei Sprints übrig, bis eine Version für die Schulungen stehen muss.
Evtl. gibt es danach Zeit für Designverbesserungen und Refactoring ...
 

Jardcore

Top Contributor
Wie wäre die Verwendung von default Werten beim Erstellen der Oberfläche? Dann kannst du sicher sein, dass initial immer false eingetragen ist.
 
Leute schreibt Unit Tests!
Aufgrund fehlender Klammern funktioniert so nicht die ternären Operationen bei der Oder-Verknüpfung müssen jeweils geklammert werden.
Code:
setBooleanA (
   ((getBooleanB() == null ? false : getBooleanB())
   || (getBooleanC() == null ? false : getBooleanC))
   ? true : getBooleanA == null ? false : getBooleanA);
 

CSHW89

Bekanntes Mitglied
Nun ja statt:
Java:
nochEinObjekt.getSuperDuperBoolean() == null ? false : nochEinObjekt.getSuperDuperBoolean()
kann man auch schreiben:
Java:
Optional.ofNullable(nochEinObjekt.getSuperDuperBoolean()).orElse(false)

Ist schon mal kürzer, und der Aufruf passiert nicht zweimal.

lg Kevin
 

Jardcore

Top Contributor
Wenn man denn Java 8 benutzen kann :p

Aufgrund fehlender Klammern funktioniert so nicht die ternären Operationen bei der Oder-Verknüpfung müssen jeweils geklammert werden.
Ist ja auch eine ganz einfache Logik-Verknüpfung ^^

setBooleanA (
((getBooleanB() == null ? false : getBooleanB())
|| (getBooleanC() == null ? false : getBooleanC))
? true : getBooleanA == null ? false : getBooleanA);
Sowas würde bei uns in der Codeabnahme auf jeden Fall nicht durchgehen.
 

Flown

Administrator
Mitarbeiter
Warum hier nicht einfach eine kleine Utility-Methode schreiben? Das sind alles Codeverdopplungen, das schreit nach einer Auslagerung?
 

nvidia

Bekanntes Mitglied
[...]
Evtl. gibt es danach Zeit für Designverbesserungen und Refactoring ...

Die wird es nicht geben, aber was genau hindert dich daran z.B. eine Methode zu schreiben die Boolean in einen boolean übersetzt, wobei null auf false abgebildet wird? Zum Beispiel:

Java:
public static boolean valueOf(Boolean value) {
        return value == null ? false : value.booleanValue();
    }

Dann sollte der Code, angenommen, es gibt ein Objekt o, sich auf Folgendes reduzieren.

Java:
        boolean result = valueOf(o.getBooleanB()) || valueOf(o.getBooleanC());
      
        if(!result){
            result = valueOf(o.getBooleanA());
        }
     
        o.setBooleanA(result);
 
Zuletzt bearbeitet:

X5-599

Top Contributor
Ich wäre eher für
Code:
boolean result = false;
result |= o.getBooleanA();
result |= o.getBooleanB();
result |= o.getBooleanC();
o.setBooleanA(result);

Müsste doch dieselbe Logik sein, oder?
 

X5-599

Top Contributor
Dann nimmste eben noch das valueOf() mit dazu. Abgesehen, dass das getBooleanC() immer ausgeführt wird, müsste das auf das selbe Ergebnis kommen.
 

stg

Top Contributor
Booleans sind nicht nullable, sondern die Variable zeigt einfach auf keinen Wert. Sprich der Boolean wurde entweder gar nicht erst erstellt oder der Variablen wurde explizit null zugewiesen. Das Problem, dass eine Referenz auf null zeigen kann, hat man überall, das ist nicht typisch für den Boolean, daher verstehe ich den ganzen Bohei, den du da veranstaltest nicht. Weise deinen Booleans einfach Initalwerte werte zu, wie du es beim primitiven boolean auch machen würdest, und deine Probleme lösen sich in Luft auf. Booleans sind im übrigens sogar immutable. Zusammengefasst: Deine Probleme, die du mit Boolean hast, deuten für mich nur auf schlampige Programmierung hin.
 

Jardcore

Top Contributor
Java:
        boolean flag = true;   
        flag &= false;
        flag &= true;
        flag &= true;
        // flag = false
Java:
        boolean flag = false;   
        flag |= false;
        flag |= true;
        flag |= true;
        // flag = true
 

X5-599

Top Contributor
Was soll mir das jetzt sagen? Meine Variante ist essenziell die gleiche Logik, die mit
Code:
boolean result = valueOf(o.getBooleanB()) || valueOf(o.getBooleanC());
        if(!result){
            result = valueOf(o.getBooleanA());
        }
     
        o.setBooleanA(result);

zustande kommt.
 
Zunächst möchte ich allen für die Beiträge danken. Genau solche unterschiedlichen Ideen habe ich mir erhofft und Java 8 löst bei mir immer wieder ein 'Aha' aus ...
Meinen Code habe ich etwas überarbeitet (besonders nach der erneuten Erkenntnis, dass wir apache comons im Projekt eingebunden haben :rolleyes: )
Java:
boolean bool = BooleanUtils.toBoolean(o1.getBooleanB()) || BooleanUtils.toBoolean(o1.getBooleanC());
o2.setBoolean1(bool ? true : BooleanUtils.toBoolean(o1.getBoolean1()));
// gab da noch eine zu setzende bool Variable ...
o2.setBoolean2(bool ? true : BooleanUtils.toBoolean(o1.getBoolean2()));
 

Ähnliche Java Themen

Neue Themen


Oben