2009-02-24 6 views
10

La syntaxe de sucre fournie par le service enum de Java peut parfois être un peu déroutante. Considérons cet exemple, qui ne compile pas:Contexte statique dans la définition enum

public enum TestEnum { 

    FOO("foo") { 
     public void foo() { 
      helper(); // <- compiler error 
     } 
    }; 

    String name; 
    TestEnum(String name) { 
     this.name = name; 
    } 

    public abstract void foo(); 

    private void helper(){ 
     // do stuff (using this.name, so must not be static) 
    } 
} 

Quelqu'un peut-il expliquer pourquoi le compilateur dit

méthode non-statique 'aide()' ne peut pas être référencé à partir d'un contexte statique

Comment exactement ce contexte est-il statique?

Vous pouvez faire cette compilation en changeant l'appel à this.helper() (ici est un point confus: si nous sommes vraiment dans un « contexte statique » comme le compilateur indique, comment peut « this » travail) ou par augmenter la visibilité de helper() au niveau par défaut. Lequel préférez-vous? Aussi, n'hésitez pas à suggérer un meilleur titre de la question :-)

Modifier: J'ai trouvé some discussion about this - mais pas de vraies réponses. Mon collègue pense que le fait que cette this.helper() fonctionne est en fait un bogue du compilateur. Et en effet avec les versions plus récentes de Java, il semble pas de travailler (bien que super.helper() fait): "ne peut pas trouver le symbole helper()". (Bien qu'il y ait quelque chose d'étrange: après avoir essayé avec différentes versions de Java je ne peux pas obtenir this.helper() pour compiler à nouveau avec l'un d'eux ...)

Répondre

0

Il y a un article mentionnant ce problème, malheureusement il est en allemand. Peut-être que vous pouvez toujours extraire des informations utiles.

EDIT: Cela semble être un problème quelque peu différent du vôtre. Je ne comprends toujours pas le comportement de votre exemple, que je vois aussi ici.

3

Quelque chose comme ceci est couvert dans le livre Java Puzzlers. IIRC, le contexte de classe externe est toujours regardé avant la super classe. Dans ce cas, l'assistant est trouvé. Mais nous construisons la valeur dans un contexte statique (il y a effectivement un private static final avant FOO). D'où l'erreur.

Essayez super.helper();.

+0

J'ai le livre; quel puzzle veux-tu dire? (Je ne pouvais pas le trouver rapidement.) – Jonik

+0

Mes deux exemplaires du livre sont emballés dans des boîtes quelque part, donc je n'en ai aucune idée. –

2

Si je traduis votre ENUM dans sa structure de classe, il se penchera à peu près comme ceci:

public abstract class TestEnum { 

    public static final TestEnum FOO = new FOO("foo") { 
    public void foo() { 
     helper(); // <- compiler error 
    } 
}; 

    String name; 
    TestEnum(String name) { 
     this.name = name; 
    } 

    public abstract void foo(); 

    private void helper(){ 
    // do stuff (using this.name, so must not be static) 
    } 

}

L'instance FOO est une classe anynomous qui s'étend TestEnum. C'est pourquoi je crois que vous ne pouvez pas accéder à helper(), parce que c'est privé. Donc, this.helper() ne devrait probablement pas fonctionner. Je ne sais pas pourquoi même super.helper() fonctionne, mais enum vous donne un accès privé au parent. En ce qui concerne l'erreur de contexte statique, je suis d'accord que le message d'erreur ne semble pas avoir de sens.

+0

Nitpick: avec "new FOO" vouliez-vous dire "new TestEnum"? – Jonik

+0

ouais attrapé aussi .. merci – richs

8

Le message d'erreur est trompeur, il suffit de protéger helper et cela fonctionnera.

protected void helper(){ 
    // can be called from subclasses (such as FOO) since it is not private 
} 
1

Vous pouvez considérer chaque constante enum comme la seule instance d'une sous-classe de la classe enum.Tout comme avec les classes "régulières", les sous-classes enum ne peuvent pas accéder aux membres privés de l'enum "super-classe". (Je ne peux pas recréer le « ce ». Le travail autour que vous mentionnez.)

Une solution raisonnable est de modifier l'accès de la méthode de privée-protected pour donner accès à la constante enum " sous-classes. "

Meilleure suggestion de titre de question: "Java enum private method?" ou juste "Méthode enum privée" (laissez la balise Java s'occuper de Java-ness)

Questions connexes