Est-il possible d'étendre enum dans Java 8?
Juste à jouer et est venu avec une façon agréable d'ajouter des fonctionnalités à enum
s dans Java Enum méthode toString() avec cette.
Quelques bricolage m'a permis de près de également ajouter une rangée (c'est à dire de ne pas jeter une exception) à rétro-interroger, mais il y a un problème. C'est de déclaration:
error: valueOf(String) in X cannot implement valueOf(String) in HasValue
public enum X implements PoliteEnum, ReverseLookup {
overriding method is static
Est-il un moyen?
Le but ici est de faire en silence ajouter (via une interface de mise en œuvre avec une default
méthode comme j'ai ajouté politeName
dans la réponse) a lookup
méthode qui ne le valueOf
fonction sans lancer une exception. Est-il possible? Il est clair maintenant possible d'étendre enum
- l'un de mes principaux problèmes avec Java jusqu'à maintenant.
Voici ma tentative a échoué:
public interface HasName {
public String name();
}
public interface PoliteEnum extends HasName {
default String politeName() {
return name().replace("_", " ");
}
}
public interface Lookup<P, Q> {
public Q lookup(P p);
}
public interface HasValue {
HasValue valueOf(String name);
}
public interface ReverseLookup extends HasValue, Lookup<String, HasValue> {
@Override
default HasValue lookup(String from) {
try {
return valueOf(from);
} catch (IllegalArgumentException e) {
return null;
}
}
}
public enum X implements PoliteEnum/* NOT ALLOWED :( , ReverseLookup*/ {
A_For_Ism, B_For_Mutton, C_Forth_Highlanders;
}
public void test() {
//Test the politeName
for (X x : X.values()) {
System.out.println(x.politeName());
}
//ToDo: Test lookup
}
source d'informationauteur OldCurmudgeon
Vous devez vous connecter pour publier un commentaire.
Vous êtes plus que compliquer votre conception. Si vous êtes prêt à accepter que vous pouvez invoquer un
default
méthode sur une instance, il y a tout le code peut ressembler à ceci:Vous pouvez le tester avec:
Un non-lancer/attraper alternative serait:
à utiliser comme:
Ici, il y a essentiellement deux points. Précisément la raison pour laquelle il ne veut pas compiler est 8.4.8.1:
En d'autres termes, un enum ne peut pas mettre en œuvre HasValue en raison du conflit de nom.
Puis il y a la question plus générale nous ont qui est que les méthodes statiques ne peuvent pas être 'remplacé'. Depuis
valueOf
est une méthode statique inséré par le compilateur sur l'énumération de la classe dérivée elle-mêmeil n'y a pas moyen de le changer. Nous ne pouvons pas utiliser les interfaces pour le résoudre, car ils n'ont pas de méthodes statiques.Dans ce cas précis c'est un endroit où la composition peut faire ce genre de chose moins répétitif, par exemple:
(Et en Plus, je le recommande qu'au cours de la capture de l'exception de toute façon.)
Je me rends compte "vous ne pouvez pas le faire" n'est pas vraiment une réponse souhaitable mais je ne vois pas un moyen de contourner cela en raison de l'aspect statique.
Le cas est le même que vous ne pouvez pas créer par défaut
toString()
dans l'interface. L'énumération contient déjà signature statiquevalueOf(String)
méthode, par conséquent, vous ne pouvez pas le remplacer.L'enum sont compiler constante de temps et parce que c'est vraiment douteux qu'ils seront extensible un jour.
Si vous voulez obtenir la constante via le nom, vous pouvez utiliser ceci:
Je pense que j'ai une réponse, c'est hacky et utilise la réflexion, mais semble correspondre à la bref - c'est à dire de recherche inversée sans les méthodes de l'enum et sans lever d'exception.
imprime
Ajouté
Inspiré par @Holger - c'est ce que je ressemble le plus à ce que je recherchais: