JavaRush /Java Blog /Random-IT /Enumerazioni in Java (java enum)
articles
Livello 15

Enumerazioni in Java (java enum)

Pubblicato nel gruppo Random-IT
Durante la programmazione, spesso incontriamo la necessità di limitare l'insieme di valori validi per un determinato tipo di dati. Quindi, ad esempio, il giorno della settimana può avere 7 valori diversi, il mese dell'anno può averne 12 e la stagione può averne 4. Per risolvere tali problemi, molti linguaggi di programmazione tipizzati staticamente forniscono un tipo di dati speciale: enumerazione ( enum). L'enumerazione non è apparsa immediatamente in Java. Un costrutto linguistico specializzato enumè stato introdotto a partire dalla versione 1.5. Fino a questo punto, i programmatori hanno utilizzato altri metodi per implementare le enumerazioni. Enumerazioni in Java (java enum) - 1

costrutto enum

Cominciamo con un esempio. enumDescriviamo il tipo di dati per memorizzare il periodo dell'anno utilizzando :
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Bene, un semplice esempio del suo utilizzo:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Di conseguenza, SUMMER verrà stampato sulla console . Penso che l'esempio sia ovvio e non abbia bisogno di spiegazioni.

Enum è una classe

Dichiarando enum, creiamo implicitamente una classe derivata da java.lang.Enum. Convenzionalmente la costruzione enum Season { ... }è equivalente a class Season extends java.lang.Enum { ... }. E sebbene il compilatore non ci consenta di ereditare esplicitamente da java.lang.Enumnoi, è comunque facile verificare che enumvenga ereditato utilizzando reflection:
System.out.println(Season.class.getSuperclass());
Sulla console verrà visualizzato quanto segue:
class java.lang.Enum
L'ereditarietà effettiva viene eseguita automaticamente per noi dal compilatore Java. Successivamente, accettiamo di chiamare la classe creata dal compilatore per implementare l'enumerazione -class enume i possibili valori del tipo enumerato come enumelementi -a.

I membri enum sono istanze enumdi una classe accessibili staticamente

Gli elementi enum Season (WINTER, SPRING и т.д.)sono istanze accessibili staticamente enumdella -class Season. La loro disponibilità statica ci consente di eseguire confronti utilizzando l'operatore di confronto di riferimento ==. Esempio:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;

Nome e numero di serie dell'elemento enum

Come accennato in precedenza, qualsiasi enumclasse eredita java.lang.Enum, che contiene una serie di metodi utili per tutte le enumerazioni. Esempio:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
L'output sarà:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
I metodi name(), toString()e sono mostrati qui ordinal(). La semantica dei metodi è ovvia. Va notato che questi metodi enumsono ereditati dalla classe java.lang.Enum. Ottenere un elemento enumtramite la rappresentazione in forma di stringa del suo nome Molto spesso si presenta il compito di ottenere un elemento enumtramite la sua rappresentazione in forma di stringa. A questi scopi, in ogni enumclasse, il compilatore crea automaticamente uno speciale metodo statico: public static EnumClass valueOf(String name), che restituisce un elemento di enumerazione EnumClasscon nome uguale a name. Esempio di utilizzo:
String name = "WINTER";
Season season = Season.valueOf(name);
Come risultato dell'esecuzione del codice, la variabile stagione sarà uguale a Season.WINTER. Tieni presente che se l'elemento non viene trovato, verrà lanciata una IllegalArgumentException e, se è nameuguale null, verrà lanciata una NullPointerException . A proposito, questo viene spesso dimenticato. Per qualche ragione, molti sono fermamente convinti che se una funzione accetta un argomento e in determinate condizioni lancia una IllegalArgumentException , quando la passa lì , nullverrà sicuramente lanciata anche una IllegalArgumentException . Ma non è questo il punto. Continuiamo. Ottenere tutti gli elementi di un'enumerazione A volte è necessario ottenere un elenco di tutti gli elementi enumdi una classe in fase di esecuzione. Per questi scopi, enumil compilatore crea un metodo in ogni -class public static EnumClass[] values(). Esempio di utilizzo:
System.out.println(Arrays.toString(Season.values()));
Otteniamo il seguente output:
[WINTER, SPRING, SUMMER, AUTUMN]
Si noti che né il metodo valueOf()né il metodo values()sono definiti nella classe java.lang.Enum. Invece, vengono aggiunti automaticamente dal compilatore quando enumviene compilata la classe. Aggiungere i propri metodi alla enum-class Hai l'opportunità di aggiungere i tuoi metodi sia alla enum-class che ai suoi elementi: Enumerazioni in Java (java enum) - 2Lo stesso, ma con polimorfismo: Enumerazioni in Java (java enum) - 3L'ultimo esempio dimostra l'uso dell'ereditarietà in enum. Ne parleremo più avanti. L'ereditarietàenum in Java enumconsente di implementare una gerarchia di classi, i cui oggetti vengono creati in una singola istanza e sono accessibili staticamente. In questo caso, gli elementi enumpossono contenere i propri costruttori. Facciamo un esempio: Enumerazioni in Java (java enum) - 4qui dichiariamo un'enumerazione Typecon tre elementi INT, INTEGERe STRING. Il compilatore creerà le seguenti classi e oggetti:
  • Type- classe derivata dajava.lang.Enum
  • INT— oggetto della 1a classe derivata daType
  • INTEGER— oggetto della 2a classe derivata daType
  • STRING— oggetto della 3a classe derivata daType
Verranno create tre classi derivate con un metodo Object parse(String)e un costruttore polimorfico Type(..., boolean). Allo stesso tempo, gli oggetti delle classi INT, INTEGERe STRINGesistono in un'unica copia e sono accessibili staticamente. Puoi verificarlo:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass()  + " " + Type.STRING.getClass().getSuperclass());
Otteniamo il seguente output:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Si può vedere che il compilatore ha creato una classe Typee 3 nestedclassi derivate da Type.

Classe enum decompilata con ereditarietà

Per confermare quanto sopra, presentiamo anche il risultato della decompilazione dell'enumerazione Typedall'esempio sopra: Enumerazioni in Java (java enum) - 5

Enumerazioni e polimorfismo parametrico

Il lettore potrebbe chiedersi: " Perché l'enumerazione Type di cui sopra non utilizza i generici? " Il fatto è che in Java è enumvietato l'uso di farmaci generici. Quindi il seguente esempio non verrà compilato:
enum Type<T> {}

Ulteriori studi

Per una comprensione più approfondita di come funzionano le enumerazioni in Java, ti consiglio di familiarizzare con il codice sorgente della classe java.lang.Enume di utilizzare anche il decompilatore Jad per studiare il codice generato. Inoltre, lo studio del codice sorgente della libreria Java è assolutamente necessario per comprendere quanti meccanismi Java funzionano ed è utile come riferimento per la progettazione orientata agli oggetti. Link alla fonte originale: http://alexander.lds.lg.ua/
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION