2012-10-18 10 views
7

In einigen unserer Unternehmens-Projekte Code Ich lese oft so etwas wie dieses:Initialisierung eines boolean mit einem Boolean.FALSE/.TRUE - warum?

boolean foo = Boolean.FALSE; 

Neben der Tatsache, dass AFAIK ich nur lokale Variablen in Java auf allen (keine Zufallswerte wie in Pascal) und neben der Initialisierung Tatsache, dass ich speziell für Booleans oft eine Initialisierung haben möchte, was vermisse ich hier? Warum nicht:

boolean foo = false; 

Ich verstehe es nicht. Und Code-Analyse-Tools wie PMD und Findbugs markieren es auch. Aber warum?

Edit: Ohne wirklich viel über den Bytecode zu wissen, außer dass es dort ist, habe ich eine Beispielklasse erstellt und es dekompiliert. Die Boolean.FALSE ging an:

0: getstatiC#15 // Field java/lang/Boolean.FALSE:Ljava/lang/Boolean; 
3: invokevirtual #21 // Method java/lang/Boolean.booleanValue:()Z 
6: istore_1 

Die ‚falsche‘ Variante ging an:

0: iconst_1 
1: istore_1 

Also ohne darüber zu viel zu wissen, ich würde vermuten, dass mehr Aussagen mehr Zeit bedeuten, so auszuführen, es ist nicht nur falsch, sondern auf lange Sicht auch langsamer.

+0

Dogmatismus, denke ich. –

+1

Die erste ist einfach nur falsche Verwendung. Obwohl Sie argumentieren könnten, dass jeder mögliche Stil, der Code noch ausführlicher macht, für Java fast idiomatisch ist. –

+0

Dies könnte sicherstellen, dass, wenn sich Boolean (Back-End) jemals ändert, dies sicherstellen wird, dass der Code immer funktioniert ..? Es sieht seltsam aus. – OmniOwl

Antwort

12
boolean foo = Boolean.FALSE; 

Dies ist seltsam und unnötig komplizierter Code, geschrieben von jemandem, der Java wahrscheinlich nicht sehr gut kannte. Sie sollten Code wie diesen nicht schreiben, und PMD und FindBugs sind berechtigt, dies zu markieren.

Boolean.FALSE ist ein java.lang.Boolean Objekt, das automatisch deaktiviert wird; der Compiler übersetzt im Wesentlichen dies:

boolean foo = Boolean.FALSE.booleanValue(); 

Ich muss nicht explizit Variablen in Java initialisieren auf allen ...

Mitglied Variablen müssen nicht initialisiert werden; Wenn nicht, werden sie mit einem Standardwert initialisiert (false im Fall boolean). Lokale Variablen müssen explizit initialisiert werden; Wenn Sie versuchen, eine lokale Variable zu verwenden, ohne sie zu initialisieren, gibt Ihnen der Compiler einen Fehler.

1

Es gibt keinen wirklichen Unterschied, obwohl die 1. Methode bei einer 1.4 oder früheren JVM nicht funktioniert. Der erste ist mehr verschachtelt, da er den statischen Wert vom Boolean-Objekt holt und sich dann auf das Autoboxing (eingeführt in 1.5) verlässt, um es von einem booleschen Objekt zu einem Booleschen Primitiv zu machen), obwohl ich mir nicht vorstellen kann, dass es jemals eine Geschwindigkeit machen würde Unterschied.

Im Allgemeinen, wenn Sie einen bestimmten Anfangswert für eine Variable annehmen, dann würde ich empfehlen, es zu initialisieren, anstatt es nur zu deklarieren, da es den Code lesbarer macht.

+0

Es gibt tatsächlich einen Unterschied. 'Boolean.FALSE' ist ein boolesches Objekt,' false' ist ein Primitiv vom Typ boolean. – jrajav

+0

Hi Kiyura, das habe ich nach dem Posten erkannt und bearbeitet um es zu korrigieren. Macht die Aufgabe noch komplizierter. – AntonyM

+0

@Kiyura Ja, aber da es einem primitiven booleschen Element zugewiesen ist, wird es sofort deaktiviert, also ist das Nettoergebnis das gleiche. Ich wäre nicht einmal erstaunt, wenn der Compiler dies optimiert hätte. –

2

Beide sind gleich. aber boolean foo = false; ist genug.

2

Der Stil zur Verwendung einer automatisch ungebetteten Konstante stimmt tatsächlich gut mit der gesamten Überverbindlichkeit überein, die bei vielen Java-Projekten auftritt. Zum Beispiel:

public boolean isItOrIsItNotTheValueWeExpect(String aStringParameterThatCouldBeNull) { 
    boolean booleanReturnValue = Boolean.FALSE; 
    if (aStringParameterThatCouldBeNull != null) { 
    if (aStringParameterThatCouldBeNull.length() > 3) { 
     booleanReturnValue = Boolean.TRUE; 
    } 
    else { 
     booleanReturnValue = Boolean.FALSE; 
    } 
    } 
    else if (aStringParameterThatCouldBeNull == null) { 
    booleanReturnValue = Boolean.TRUE.booleanValue(); 
    } 
    return booleanReturnValue; 
} 

Offensichtlich würde der Code über viel zu diesem unleserlich Chaos bevorzugt sein:

public boolean validate(String s) { 
    return s == null? true : s.length() > 3; 
} 

Das sehr Auftreten eines ternären Operators betrachtet wird es eine Übertretung und einige Projekte auch durch gekennzeichnet haben CheckStyle.

Wenn Ihre Projekte solchen stilistischen Richtlinien entsprechen, könnte dies Ihre verdächtige Codezeile rechtfertigen.

+0

Ich habe persönlich festgestellt, dass der ternäre Operator zu mächtig ist - da er eine Verzweigung in den Programmfluss einführen kann, ohne explizit mit dem Schlüsselwort "if" gekennzeichnet zu sein. Prägnanz bedeutet nicht Wartbarkeit. –

+0

@ ThorbjørnRavnAndersen Da gehts dann, du solltest die CheckStyle-Regel gegen ternäre Operatoren aktivieren :) –

+0

Oh man, wenn mir jemand meine ternaries wegnimmt, würde ich tagelang weinen. – yshavit

2

Es gibt keinen guten Grund, dies zu tun, es war wahrscheinlich nur ein Anfänger Java-Programmierer. Ich würde mir nicht zu viele Sorgen machen, sondern einfach durch falsch ersetzen.

Gleichzeitig können Sie Ihren Code normalerweise so arrangieren, dass Sie niemals eine Variable deklarieren, für die Sie nicht den endgültigen Wert haben, d. H. Ihre Objekte unveränderlich machen, was ihnen das Nachdenken erleichtert. Was ist der Wert von x? verglichen mit Was ist der Wert von x zwischen den Aufrufen von foo() und bar()? Der erste ist in der Regel einfacher zu beantworten. Dies erfordert, dass Sie Ihre Klassen nach Linien aufteilen, die Sie vielleicht nicht gewohnt sind, aber ich empfehle zumindest, es auszuprobieren.

Verwandte Themen