Un enum
in Java ha un costruttore predefinito quando non è definito ed è privato.
Il modificatore di accesso predefinito ha significati diversi in ambiti diversi. Ad esempio all'interno di un modificatore di accesso predefinito di classe per metodi e campi è package private
.
Dove come in un modificatore di accesso predefinito di interfaccia significa public
. In realtà non ci può essere nessun altro modificatore su un campo di interfaccia quindi è implicitamente pubblico.
Su una classe di livello superiore E 'pacchetto privata (dove solo 2 modificatori di accesso sono consentiti public
e pacchetto predefinito privato)
Quindi la risposta alla tua domanda è che è così perché il compilatore decide così. Lo scrittore di compilatori ha dovuto sostenere il contratto di specifica della lingua.
Hai ragione nel pensare che è una classe normale dopo tutto. Ogni tipo di blueprint di un oggetto in java è una classe che può essere rappresentata da java.lang.Class
. Queste restrizioni per interfacce, enumerazioni, classi astratte, classi anonime, classi locali dei metodi sono validate solo dal compilatore.
Se è possibile in qualche modo sfuggire al compilatore e generare il proprio codice byte per enumerazione o altro modo se è possibile modificare il codice byte della classe generata enum
in modo che il costruttore privato diventi pubblico potrebbe essere possibile chiamarlo costruttore al di fuori dell'ambito privato dell'enum. Puoi anche provare a sperimentare con la riflessione per fare lo stesso. Infatti generando codice byte manualmente i linguaggi JVM come Groovy, Jython, JRuby, Clojure sono in grado di fornire funzionalità che non sono in Java stesso. Stanno bypassando il compilatore java.
Scopo per il costruttore in enum
s è essere in grado di impostare campi di costanti in una chiamata. Tutte le costanti all'interno di enum
sono istanze della classe enum
, quindi sono anche i campi dichiarati in essa.
enum Test
{
T1(1), // equivalent to public static final Test T1 = new Test(1);
T2(2); // equivalent to public static final Test T2 = new Test(2);
int id;
Test(int id)
{
this.id = id;
}
}
Infine soffietto è l'uscita di codice decompilato per sopra enum
utilizzando java -p Test.class
final class Test extends java.lang.Enum<Test>
{
public static final Test T1;
public static final Test T2;
int id;
private static final Test[] $VALUES;
public static Test[] values();
public static Test valueOf(java.lang.String);
private Test(int);
static {};
}
Si dovrebbe dare una migliore comprensione di ciò che accade quando la classe compila.
"Perché la lingua lo dice." Davvero, non c'è risposta migliore di quella. La tua dichiarazione 'enum' fa in modo che quattro oggetti siano _pre-created_, e ogni oggetto della classe deve essere uno di questi quattro. Quindi non c'è mai un motivo per istanziarne un altro. – ajb
Nota a margine: un 'enum Year' è compilato in un' classe finale Anno Enum '. –
Seelenvirtuose