Spécialisée enum
n'est rien mais une sous-classe à l'intérieur de la classe sémantique. Si vous regardez le code octet après compilation, vous verrez que le compilateur insère uniquement méthode d'accesseur pour la lecture d'un domaine privé, mais spécialisé enum est réalisé de sa propre classe. Vous pouvez penser au sujet de votre enum
que la mise en œuvre:
public abstract class MyEnum {
private static class First extends MyEnum {
@Override
public String doIt() {
return "1: " + someField; //error
}
}
private static class Second extends MyEnum {
@Override
public String doIt() {
return "2: " + someField; //error
}
}
public static final MyEnum FIRST = new First();
public static final MyEnum SECOND = new Second();
private String someField;
public abstract String doIt();
}
Comme vous pouvez le voir, le même compilateur des erreurs se produisent. Effectivement, votre problème ne concerne pas enum
s, mais à l'intérieur de la classe sémantique.
Cependant, vous avez trouvé un cas limite du compilateur de deviner l'intention de votre code et de vous avertir que ce que vous avez l'intention est illégal. En général, l' someField
champ est visible à tout spécialisée enum
. Cependant, il y a deux manières d'accéder à l' private
domaine à partir d'un noyau de classe et un seul est légal:
private
des membres ne sont pas héritées. Vous ne pouvez donc pas accéder à un private
champ d' this
instance où elle a été définie dans une classe super.
Pour les classes internes, les membres de l'classes sont accessibles, même si elles sont private
. Ceci est réalisé par le compilateur en insérant des méthodes d'accès à l'extérieur des classes qui exposent l' private
champs par des méthodes accesseurs. Un non-static
champ ne peut être accessible que si l'intérieur de la classe est non-static
. Pour enum
s, les classes internes sont cependant toujours static
.
Le plus tard condition est que le compilateur se plaint:
Ne peut pas faire une référence statique pour les non-champ statique someField
Vous essayez d'accéder à une non-static
de static
intérieur de la classe. Ce n'est pas possible, même si le champ doit être techniquement visible que de l'intérieur de la classe sémantique. Vous pourriez demander au compilateur explicitement pour accéder à la valeur par la lecture de la super-classe, par exemple:
public String doIt() {
MyEnum thiz = this;
return thiz.someField;
}
Maintenant que le compilateur sait que vous essayez d'accéder à un membre d'un visible (extérieur) - type au lieu de tort accès à l' someField
domaine de la (non statique) externe instance de classe (qui n'existe pas). (De même, vous pouvez écrire super.someField
qui exprime la même idée que vous voulez aller en bas de la chaîne d'héritage et de ne pas accéder à l'extérieur de l'instance du champ.) La solution facile serait cependant tout simplement de rendre le champ protected
. De cette façon, le compilateur est heureux au sujet de l'héritage de la visibilité et de la compilation de vos installation d'origine.