2012-10-18 21 views
7

In alcuni dei nostri progetti companys codice Leggo spesso qualcosa di simile:Inizializzazione di un booleano con un valore booleano.FALSE/.TRUE - perché?

boolean foo = Boolean.FALSE; 

Oltre al fatto che per quanto ne so io hanno solo per inizializzare le variabili locali in Java a tutti (senza valori casuali come in Pascal) e oltre il Infatti, soprattutto per i booleani, VOGLIO spesso avere un'inizializzazione, cosa mi manca qui? Perché no:

boolean foo = false; 

Non capisco. E anche gli strumenti di analisi del codice come PMD e Findbugs lo contraddistinguono. Ma perché?

Modifica: Senza sapere molto sul bytecode tranne che è lì ho creato una classe di esempio e decompilato. Il Boolean.FALSE è andato a:

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

La variante 'false' andato a:

0: iconst_1 
1: istore_1 

Quindi, senza sapere troppo su questo, direi che più istruzioni significa più tempo per eseguire in modo non è solo sbagliato, ma anche più lento nel lungo periodo.

+0

Dogmatismo, immagino. –

+1

Il primo è solo un uso sbagliato. Sebbene si possa obiettare che ogni possibile stile che rende il codice ancora più prolisso è quasi ** idiomatico ** in Java. –

+0

Questo potrebbe essere per assicurarsi che se Boolean (back-end) dovesse mai cambiare, questo assicurerà che il codice funzioni sempre ..? Sembra strano – OmniOwl

risposta

12
boolean foo = Boolean.FALSE; 

Questo è un codice strano e inutilmente complicato, scritto da qualcuno che probabilmente non conosceva Java molto bene. Non dovresti scrivere codice come questo, e PMD e FindBugs hanno ragione nel segnarlo.

Boolean.FALSE è un oggetto java.lang.Boolean che viene annullato automaticamente; il compilatore traduce essenzialmente questo:

boolean foo = Boolean.FALSE.booleanValue(); 

non devo per inizializzare le variabili in Java a tutti ...

variabili Stati non hanno bisogno di essere inizializzato in modo esplicito; in caso contrario, verranno inizializzati con un valore predefinito (che è false nel caso di boolean). Le variabili locali devono essere esplicitamente inizializzate; se si tenta di utilizzare una variabile locale senza inizializzarla, il compilatore ti darà un errore.

1

Non c'è alcuna differenza in realtà anche se il 1o metodo non funzionerà su una JVM 1.4 o precedente. Il primo è più complicato dal momento che recupera il valore statico dall'oggetto booleano e quindi fa affidamento sull'autoboxing (introdotto in 1.5) per cambiarlo da un oggetto booleano a un primitivo booleano) sebbene non riesca a immaginare che possa mai accelerare differenza.

In genere, tuttavia, se si assume un valore iniziale particolare per una variabile, si consiglia di inizializzarlo anziché dichiararlo in quanto rende il codice più leggibile.

+0

In realtà c'è una differenza. 'Boolean.FALSE' è un oggetto booleano,' false' è una primitiva di tipo booleano. – jrajav

+0

Ciao Kiyura, l'ho capito dopo averlo postato e modificato per correggerlo. Rende il compito ancora più complicato. – AntonyM

+0

@Kiyura si, ma dal momento che è stato assegnato a un booleano primitivo, verrà immediatamente rimosso, quindi il risultato netto è lo stesso. Non sarei nemmeno sorpreso se il compilatore lo ottimizzasse. –

2

Entrambi sono uguali. ma boolean foo = false; è sufficiente.

2

Lo stile per utilizzare una costante auto-unboxed Boolean si integra bene con la sovrabbondanza generale endemica di molti progetti Java. Ad esempio:

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; 
} 

Ovviamente, il codice precedente sarebbe molto preferivano questo caos illeggibile:

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

La stessa presenza di un operatore ternario è considerata una trasgressione e alcuni progetti anche avere segnalato dalla CheckStyle.

Se i vostri progetti sono conformi a tali linee guida stilistiche come questi, ciò potrebbe giustificare la vostra sospetta riga di codice.

+0

Ho scoperto personalmente che l'operatore ternario è troppo potente, in quanto può introdurre un fork nel flusso del programma senza essere esplicitamente contrassegnato con la parola chiave if. La concisione non implica la manutenibilità. –

+0

@ ThorbjørnRavnAndersen Ecco qua, dovresti abilitare la regola CheckStyle contro gli operatori ternari :) –

+0

Oh uomo, se qualcuno mi togliesse i ternari, piangerei per giorni. – yshavit

2

Non c'è una buona ragione per farlo, probabilmente era solo un programmatore Java principiante. Non mi preoccuperei troppo, sostituiscilo con false.

Allo stesso tempo, in genere è possibile non organizzare il codice in modo tale da non dichiarare mai una variabile per cui non si ha il valore finale, ovvero rendere immutabili gli oggetti, il che li rende più facili da pensare. Qual è il valore di x? rispetto a Qual è il valore di x tra le chiamate a foo() e bar()? Il primo è generalmente più facile da rispondere. Ciò richiede di dividere le classi lungo linee che potresti non essere abituate a fare, ma consiglio almeno di provarlo.

Problemi correlati