Domanda

Se hai una situazione in cui devi sapere dove non è stato impostato un valore booleano (ad esempio se quel valore non impostato deve ereditare da un valore padre) la primitiva booleana Java (e l'equivalente in altre lingue) non è chiaramente adeguata.

Qual è la migliore pratica per raggiungere questo obiettivo? Definire una nuova classe semplice in grado di esprimere tutti e tre gli stati o utilizzare la classe booleana Java e utilizzare null per indicare lo stato non impostato?

È stato utile?

Soluzione

Boolean a = true;
Boolean b = false;
Boolean c = null;

Lo userei. È il più diretto.

Un altro modo è usare un'enumerazione. Forse è ancora meglio e più veloce, dal momento che non è richiesta la boxe:

public enum ThreeState {
    TRUE,
    FALSE,
    TRALSE
};

C'è il vantaggio del primo che gli utenti della tua classe non devono preoccuparsi del tuo booleano a tre stati. Possono comunque passare true e false . Se non ti piace il null , dato che qui sta dicendo poco sul suo significato, puoi comunque creare un booleano tralse finale statico pubblico = null; nella tua classe.

Altri suggerimenti

In Java 8, c'è anche l'opzione Opzionale :

public static final Optional<Boolean> TRI_TRUE = Optional.of(true);
public static final Optional<Boolean> TRI_FALSE = Optional.of(false);
public static final Optional<Boolean> TRI_UNKNOWN = Optional.empty();

Come bonus, otterrai tutti quei metodi mappa e consumati .

Sebbene non sia specifico di Java, la mia preferenza in questo scenario è definire una classe o enumerazione ThreeState e usarla - proprio come hai detto, un True, un False e un Undefined (o Default, o Unset, come tuo dettami terminologici specifici del dominio). È meglio, più naturale e più autocompattante rispetto a rappresentare non impostato / non definito con null .

Il @Nullable Booleano ottiene il mio voto.

L'uso di null per rappresentare lo stato di qualcosa è un progetto scadente. È descrittivo e difficile da mantenere. Preferirei avere un oggetto State con uno stato predefinito se non è stato impostato esplicitamente su di esso. Ad esempio:

if(state == null) {
    doSomething();
}

Questo non mi dice nulla su quale sia lo stato previsto. Qualcosa di più come questo rende più chiaro.

if(state.awaitingSet()) {
    doSomething();
}

Per non parlare dell'estensibile. Cosa succede quando è necessario un quarto stato?

Dipende. Qui dici che non sarebbe impostato se dovesse ereditare il suo valore da un valore genitore. Hai qualche tipo di gerarchia dei dati? Qualcosa del genere:

Parent a { 
    boolean val = true;
    boolean val2 = false; 
}
Child b {
    boolean val = false;
    //here val2 should be unset!
}

In questo caso, se possibile, direi semplicemente di non includere val2 in Child e di avere una logica di ricerca tale che se non trova la variabile, cerca il valore tra i genitori.

Vorrei semplicemente usare un int (intero) con valori 0,1,2 e gestirlo all'interno del programma.

Per aggiungere a @voho, Opzionale gioca bene anche con lambda, rendendo una struttura potenzialmente più pulita:

public class Node {
  private Node parent;
  private Optional<Boolean> something = Optional.empty();

  public boolean isSomething() {
    return something.orElseGet(() -> {
      if (parent != null)
        return parent.isSomething();
      return false;
    });
  }

  public void setSomething(boolean v) {
    this.something = Optional.of(v);
  }
}

Tuttavia, ovviamente non è ancora molto meglio di Boolean e un controllo null:

public class Node {
  private Node parent;
  private Boolean something;

  public boolean isSomething() {
    if (something != null)
      return something;
    if (parent != null)
      return parent.isSomething();
    return false;
  }

  public void setSomething(boolean v) {
    this.something = v;
  }
}

Nella classe Parent avvia il valore booleano su null e nella classe figlio crea un metodo per verificare se il valore booleano è stato impostato

nella classe Parent

private Boolean a = null;

public void setA(Boolean a) {
    this.a = a;
}


public Boolean getA() {
    return a;
}

Nella classe Child

if (a == true)
{
dothis;
}
else if (a == false)
{
dothat;
}
else
{
assert false : "Boolean a has not been set";
}

Assicurati che le asserzioni siano attivate. Le asserzioni sono solo per il ciclo di sviluppo e il ciclo di test, non per le eccezioni di runtime.

java.lang.Boolean fa questo per te. Esistono costanti statiche Boolean.TRUE, Boolean.False.

myBoolean booleano privato;

dovrebbe essere tutto ciò di cui hai bisogno. Nota che Boolean.TRUE supererà un test di equivalenza ma è distinto da " true " (che viene impostato automaticamente su VERO).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top