2009-02-24 19 views
10

Lo zucchero di sintassi fornito dalla funzione Java enum può a volte creare confusione. Considerate questo esempio, che non può essere compilato:Contesto statico nella definizione 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) 
    } 
} 

qualcuno può spiegare il motivo per cui il compilatore dice

metodo non statico 'helper()' non è possibile fare riferimento da un contesto statico

In che modo esattamente questo contesto è statico?

È possibile effettuare questa compilazione cambiando la chiamata a this.helper() (qui è un punto di confusione: se siamo davvero in un "contesto statico" come il compilatore suggerisce, come si può "this" lavorare) o aumentando la visibilità di helper() al livello predefinito. Quale preferiresti? Inoltre, sentitevi liberi di suggerire una migliore titolo della domanda :-)

Edit: Ho trovato some discussion about this - ma nessuna risposta. Il mio collega pensa che il fatto che lo this.helper() funzioni sia in realtà un bug del compilatore. E infatti con le nuove versioni di Java sembra che non sia funzionante (sebbene lo sia super.helper()): "impossibile trovare l'helper di simbolo()". (Anche se c'è qualcosa di strano: dopo aver provato con diverse versioni Java non riesco a ottenere this.helper() per compilare di nuovo con nessuno di loro ...)

risposta

0

C'è un article che menziona questo problema, purtroppo è in tedesco. Forse puoi ancora estrarre alcune informazioni utili.

MODIFICA: sembra essere un problema un po 'diverso dal tuo. Continuo a non capire il comportamento del tuo esempio, che vedo anche qui.

3

Qualcosa di simile è coperto nel libro Java Puzzlers. IIRC, il contesto di classe esterna è sempre visto prima della super classe. In questo caso viene trovato l'helper. Ma stiamo costruendo il valore in un contesto statico (c'è effettivamente un private static final prima di FOO). Quindi l'errore.

Prova super.helper();.

+0

Ho il libro; quale enigma vuoi dire? (Non sono riuscito a trovarlo rapidamente.) – Jonik

+0

Entrambe le mie copie del libro sono imballate in scatole da qualche parte, quindi non ne ho idea. –

2

Se traduco il tuo enum nella sua struttura di classe che avrà un aspetto approssimativamente simile a questo:

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) 
    } 

}

Il FOO esempio è una classe che si estende anynomous TestEnum. Ecco perché credo che non puoi accedere a helper(), perché è privato. Quindi this.helper() probabilmente non dovrebbe funzionare. Non sono sicuro del perché anche super.helper() funzioni, ma forse enum ti dà l'accesso privato al genitore.

Per quanto riguarda l'errore di contesto statico, sono d'accordo sul fatto che il messaggio di errore non sembra avere senso.

+0

Nitpick: con "nuovo FOO" intendevi "nuovo TestEnum"? – Jonik

+0

yeah colto anche questo .. grazie – richs

8

Il messaggio di errore è fuorviante, basta rendere helper protetto e funzionerà.

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

si può pensare di ogni enum costante come l'unica istanza di una sottoclasse della classe enum.Proprio come con le classi "regolari", le "sottoclassi" di enum non possono accedere ai membri privati ​​dell'enum "super-classe". (Non riesco a ricreare il "questo". Work-around che si parla.)

Una soluzione ragionevole è quella di modificare l'accesso metodo dal privato-protetta per dare accesso al enum costante " sottoclassi."

Suggerimento per il titolo della domanda migliore: "metodo Java enum privato?" o semplicemente "Metodo enum privato" (lascia che il tag Java si prenda cura della Java-ness)

Problemi correlati