Question

Si vous devez savoir où une valeur booléenne n'a pas été définie (par exemple, si cette valeur non définie doit hériter d'une valeur parente), la primitive booléenne Java (et l'équivalent dans d'autres langues) n'est clairement pas adéquat.

Quelle est la meilleure pratique pour y parvenir? Définir une nouvelle classe simple capable d’exprimer les trois états ou utiliser la classe Java Boolean et utiliser null pour indiquer l’état non défini?

Était-ce utile?

La solution

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

J'utiliserais ça. C'est le plus simple.

Une autre méthode consiste à utiliser une énumération. C’est peut-être encore mieux et plus rapide, puisqu’aucune boxe n’est requise:

public enum ThreeState {
    TRUE,
    FALSE,
    TRALSE
};

Le premier avantage est que les utilisateurs de votre classe n’ont pas besoin de se soucier de votre booléen à trois états. Ils peuvent toujours transmettre true et false . Si vous n'aimez pas null , étant donné qu'il en dit assez peu sur sa signification ici, vous pouvez toujours créer un public statique final Boolean tralse = null; dans votre classe.

Autres conseils

Dans Java 8, l'option Facultatif est également disponible:

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();

En prime, vous obtiendrez toutes ces méthodes map et consommer .

Bien que n'étant pas spécifique à Java, ce que je préfère dans ce scénario est de définir une classe ou une énumération ThreeState et de l'utiliser - comme vous l'avez mentionné, une valeur True, False et Undefined (ou Default ou Unset). la terminologie spécifique au domaine). Cela se sent mieux, plus naturel et auto-documenté que de représenter non défini / indéfini avec null .

Le @Nullable Boolean obtient mon vote.

L'utilisation de valeurs NULL pour représenter l'état d'un objet est de conception médiocre. C'est descriptif et difficile à maintenir. Je préférerais avoir un objet State avec un état par défaut si rien n'a été explicitement défini dessus. Par exemple:

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

Cela ne me dit rien sur l'état attendu. Quelque chose de plus semblable à ceci le rend plus clair.

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

Sans parler de l'extensible. Que se passe-t-il lorsque vous avez besoin d'un quatrième ?

Cela dépend. Ici, vous mentionnez qu'il serait non défini s'il doit hériter de sa valeur d'une valeur parent. Avez-vous une sorte de hiérarchie de données? Quelque chose comme ça:

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

Dans ce cas, si cela est possible, je dirais tout simplement de ne pas inclure val2 dans l’enfant et que votre logique de recherche soit telle que, si elle ne trouve pas la variable, elle recherche la valeur dans les parents.

Je voudrais simplement utiliser un int (entier) avec les valeurs 0,1,2 et le gérer dans le programme.

Pour ajouter à @voho, Optional joue également bien avec lambda, créant ainsi une structure potentiellement plus propre:

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

Cependant, il est évident que ce n'est pas beaucoup mieux que Boolean et une vérification nulle:

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

Dans la classe Parent, initialisez le booléen à la valeur null et dans la classe enfant, créez une méthode pour vérifier si le booléen a été défini

dans la classe parente

private Boolean a = null;

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


public Boolean getA() {
    return a;
}

Dans la classe des enfants

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

Assurez-vous que les assertions sont activées. Les assertions ne concernent que le cycle de développement et le cycle de test, pas les exceptions d'exécution.

java.lang.Boolean le fait pour vous. Il existe des constantes statiques Boolean.TRUE, Boolean.False.

private Boolean myBoolean;

devrait être tout ce dont vous avez besoin.Notez que Boolean.TRUE passera un test d’équivalence mais sera distinct de "true". (qui devient automatique à TRUE).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top