Je fais face à certains travaux concernant des endroits où j'ai utilisé des représentations de chaîne ou int intempestives de partie du modèle, et en utilisant Enum et EnumSet les meilleures pratiques.Meilleure initialisation pour un EnumSet <E> maintenu par l'instance de E
Une difficulté particulière est ce cas d'utilisation: un Enum où chaque instance est titulaire d'un EnumSet de [0..n] de ses propres sœurs.
Pour dépouiller à l'essentiel ma question que je reposeront sur StyleEnum de Joshua Bloch. Nous avons donc une enum de BOLD, ITALIQUE, UNDERLINE, STRIKETHROUGH .. et imaginons un B_AND_I qui tiendra {BOLD, ITALIC}.
S'il vous plaît, ne prenez pas beaucoup de sens l'exemple: dans le système réel c'est construit sur des sous-ensembles de base de certaines règles changeantes chargées @ temps de démarrage.
L'objectif est qu'une fois que ce calcul a eu lieu, rien ne peut changer par exemple gamme sous-EnumSet particulier. Alors je viens avec quelque chose comme ceci:
public enum StyleEnum {
NONE(0, "none"), BOLD(100, "B"), ITALIC(250, "i"), UNDERLINE(350, "u"), STRIKETHROUGH(9, "b"), B_AND_I(99,"Emphase");
//// Pure dream == private final EnumSet<StyleEnum> complexComputedSubSet = new EnumSet<StyleEnum>();
//// But not in the jdk
private final EnumSet<StyleEnum> complexComputedSubSet;
private final int intProp;
private final String strLabel;
StyleEnum(int intProp, String strLabel) {
this.intProp = intProp;
this.strLabel = strLabel;
//// option 2 would have been be this
// complexComputedSubSet = EnumSet.of(NONE);
//// But COMPILER :: illegal reference to static field from initializer
}//.... end of constructor
/**
* static initialzer will compute based on some rules a subset of (none) or
* others Enum, a particular enum instance can holds in his bag.
*/
static {
//// at least, as option 3, why not this...
// for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
// e.complexComputedSubSet = EnumSet.of(NONE);
// }
//// COMPILER :: cannot assign a value to final variable complexComputedSubSet
// main handling here : at class loading
// compute a set (rules coming from whatever you want or can).
//Once this static class level init is done
// nothing can change the computed EnumSet
// it's getter will always return an unmodifiable computed EnumSet
//.... computing something
}
//....
//getter(){}
//whateverelse(){}
}
Comme vous pouvez le voir rien est vraiment agréable ou tout au moins élégant ici.
Dans mes rêves:
private final EnumSet<StyleEnum> complexComputedSubSet= new EnumSet<StyleEnum>();
//..
//static initialzer
static {
EnumSet.allOf(StyleEnum.class).forEach(e-> computeSubSet(e));
//..
}
private static void computeSubSet(StyleEnum instance){
//...
instance.complexComputedSubSet.addAll(someComputedCollection);
}
Et voilà!
Au lieu de cela, tout ce que je peux faire semble éloigner la finale sur le terrain
// getting away from the final keyword
private EnumSet<StyleEnum> complexComputedSubSet;
puis dans la boucle de bloc initialiseur statique theClass et instancier avec le marqueur (factice) (NONE) introduite seulement pour ce (stupide) but:
for (StyleEnum e : EnumSet.allOf(StyleEnum.class)) {
e.complexComputedSubSet = EnumSet.of(NONE);
}
Et seulement après cela calculer et stocker le sous-EnumSet.
Alors toute cette douleur, -mostly-, juste parce que l'on ne peut pas dire « nouvelle EnumSet(); » ? Il doit y avoir un meilleur moyen? Pouvez-vous s'il vous plaît me diriger vers la bonne direction?
Ne devrait pas 'e.complexComputedSubSet = EnumSet.copyOf (someComputedCollection);' être suffisant? Vous devez toujours supprimer le mot clé 'final' mais cela ne devrait pas faire de mal. – Thomas
BTW, je pense que 'EnumSet.noneOf (StyleEnum.class)' doit être équivalente à la 'nouvelle EnumSet(); Vous êtes après. Les états JavaDoc: "Crée un ensemble d'énumération vide avec le type d'élément spécifié." - Ce nom de méthode est très regrettable que :) –
Thomas
Ce fut l'un de mes premiers vraiment attemps: 'privé EnumSet complexComputedSubSet = EnumSet.noneOf (StyleEnum.class);' \t mais cette ligne mignonne résout dans cette trace effrayant : \t ** 'causée par: java.lang.ClassCastException: classe entity.StyleEnum pas enum' ** ' à java.util.EnumSet.noneOf (EnumSet.java:112) '' à entity.StyleEnum. (StyleEnum.java:22) ' ' at entity.StyleEnum. (StyleEnum.java: 5) ' \t Je viens donc de quitter son utilisation. –