Si vous définissez une valeur null/valeur inconnue pour Java énumérations?
Lorsque vous définissez un enum pour quelque chose qui peut être "undefined" dans vos interfaces, si vous
- définir un distinct valeur d'enum pour cela, ou à
- suffit d'utiliser enumValue = null pour ces situations?
Par exemple,
serviceX.setPrice(Prix priceEnum)
enum Price {
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE, UNKNOWN
}
et priceEnum.INCONNU si nécessaire
ou
enum Price {
CHEAP, EXPENSIVE, VERRRY_EXPENSIVE
}
et priceEnum = null lorsque nécessaire?
D'avoir un peu de débat sur ce point. Quelques points qui me viennent à l'esprit:
- à l'aide de Prix.INCONNU enregistre quelques "si (prix == null)" du code. Vous pouvez gérer les Prix de x toutes les valeurs dans un seul cas de commutateur
- En fonction de la vue de la technologie, il peut être plus facile de localiser les Prix.INCONNU
- à l'aide de Prix.INCONNU genre de causes "nombre magique" problème dans le code, de l'OMI. Ici, nous avons des Prix.INCONNU, d'ailleurs peut-être de Couleur.UNDEFINED, Hauteur.NULLVALUE, etc
- à l'aide de priceValue = null est plus uniforme avec comment d'autres types de données sont traitées en Java. Nous avons Integer i = null, DomainObject x = null, String s = null pour les valeurs inconnues ainsi, n'est-ce pas?
- Prix.INCONNU force à vous de décider si la valeur null est autorisée univerally pour tous les cas d'utilisation. On peut avoir de la méthode des Prix getPrice() qui peut retourner des Prix.INCONNU et setPrice(Prix p), ce qui n'est pas autorisé à accepter des Prix.INCONNU. Puisque Le Prix.INCONNU est toujours inclus dans l'énumération de valeurs, ces interfaces air un peu sale. Je sais priceValue = null a le même problème (vous ne pouvez pas définir dans l'interface si null est accepté ou pas) mais il se sent un peu plus propre et un peu moins induire en erreur(?)
- vous ne pouvez pas utiliser
null
dans un switch et c'est un inconvénient majeur. - Bons points par tous. Réduire le fardeau de la valeur null, la gestion et la capacité d'être plus précis sur ce que "valeur nulle" les moyens sont bons points pro Prix.INCONNU. Aussi, bon point sur "l'objet null modèle", il fait des Prix.INCONNU se sentir comme plus "valide" et communément acceptée de la solution. Mais, personne ne se sent de la même façon sur les Prix.INCONNU aspects négatifs? Je me sens avoir de Prix.INCONNU pollue l'enum de la valeur de consigne. Dire dans showAllPrices(), je ne peux pas énumérer toutes les valeurs de l'enum plus, j'ai à ajouter, si (!Prix.INCONNUE), qui se sent un peu sale et "la magie numbery".
- @user449236: Si vous n'aimez pas la vérification de cette valeur spéciale, ajouter un
display
drapeau à chaque enum et de les vérifier à la place. Plus propre et plus flexible. - voir, c'est simple, Prendre C par exemple, vous ne pouvez pas avoir une valeur null pour les types enum (comme ils le sont en réalité de vrais int). Dans ma compréhension de la non-déclaration de valeur (c'est à dire nulle) est une mauvaise pratique et généralement une erreur. Non déclarées valeurs ne dites pas que le but est, c'est à dire qu'il doit être ignoré, il a été à la suite d'une erreur (par conséquent et à l'exception devrait [ont] être jetés)
- Un (très en retard) des commentaires sur cette. Dans mon expérience - si vous écrivez du code qui doit être réutilisé, l'extension ou la partie de l'API, vous aurez à rendre compte de code client en passant ou d'un paramètre null toute façon robuste. Et que généralement réduit par rapport à tous les avantages d'un régime spécial de Foo.Valeur NIL. Il rend également plus difficile d'écrire un type agnostique méthodes / utils, car ils ne le feront pas (en général) être conscient que l'une des valeurs est "spécial".
Vous devez vous connecter pour publier un commentaire.
C'est en fait un exemple de l'application de Objet Null modèle. À mon humble avis, il est toujours préférable d'avoir un objet fictif plutôt que null. Par exemple, vous pouvez ajouter mannequin méthodes null-objet plutôt que d'éparpiller votre code avec la valeur null-vérifie tous sur la place. Très pratique.
Aussi le nom de la
enum
vous donne d'autres sémantique: le prix inconnu, undefined, pas digne de confiance, pas encore connu? Et que signifie-t-il si le prix est null?Mise à JOUR: Comme Aaron Digulla le souligne, l'Objet Null modèle nécessite de la mémoire. Mais ce n'est pas vraiment le cas la plupart du temps. Dans la tradition de la mise en œuvre généralement, vous avez un singleton pour objet Null utilisé un peu partout, comme il n'est pas nécessaire pour des instances distinctes. C'est même encore mieux avec les énumérations, parce que vous obtenez singleton sémantique gratuitement.
Un autre point est que
null
de référence et la référence à un objet occupent la même quantité de mémoire (4 octets sur une machine 32 bits). C'est l'objet référencé que occupe de la mémoire supplémentaire. Mais si c'est un singleton, il n'y a pratiquement pas de surcharge de la mémoire ici.null
les pointeurs n'ont pas besoin de la mémoire). Mais ils oublient que ce qui rend le code plus complexe (-> plus de temps passé à développer et déboguer), la complexité est fortement liée au nombre de bugs et plus de lignes de code signifie que le code besoin de plus de mémoire, de sorte que la décision est souvent une perte sur tous frontières.The main reason why people don't use the pattern is because it needs memory (null pointers don't need memory)
principale raison de la performance est nulle, les contrôles sont facilement éliminés par le JIT, null contrôles sont assistée par matériel et ainsi de suite.Je dirais aller avec
Price.UNKNOWN
si c'est une valeur valide pour un prix.Je suis d'accord avec les inconvénients de traiter avec des références nulles, que vous citez, et je pense qu'ils motiver la décision assez.
De nouveaux langages, de prendre Scala par exemple (et pour certains, plus âgés, Haskell) de la souche loin de références nulles tous ensemble et utilise l'option /peut-être monades à la place... pour de bonnes raisons.
Ça dépend comment allez-vous utiliser cette enum. Si vous utilisez le commutateur/cas les déclarations qu'il n'a pas d'importance.
Si vous créez méthode(s) dans l'enum en fait vous devez définir INCONNU.
Par exemple, vous pouvez définir la méthode abstraite
public abstract Icon icon();
dans votre enum et de mettre en œuvre cette méthode pour chaque membre de Prix. Probablement vous voulez afficher le point d'interrogation pour prix inconnu. Dans ce cas il suffit de mettre en œuvre la méthode
icon()
qui crée l'icône appropriée.Il est le Enum-Commutateur-Null-Trap.
Il semble donc que, comme pour n'importe quelle propriété d'un objet,
s'il n'existe pas, alors il est
null
.De la couleur ou de la Hauteur seront utilisés dans la logique du programme. Eux ne peuvent pas gérer avec un indéfini de couleur.
Un Prix est userdata et peut-être inconnu.
La couleur peut être userdata d'autre, mais à être utilisé comme couleur dans le code, ils doivent être définis.
Donc le Prix peut être INCONNUE (au lieu de null), la Couleur (null peuvent signaler une erreur).