Enumerazione in Java

Enum è stato introdotto in Java 1.5 come un nuovo tipo il cui campi consistono in un insieme fisso di costanti. Ad esempio, possiamo creare direzioni come Enum Java con campi fissi come EAST, WEST, NORTH e SOUTH.

Enum Java

In questo tutorial, impareremo come creare un Enum. Esamineremo anche i vantaggi dell’uso degli enum in Java e le caratteristiche dei tipi di enum. Impareremo anche ad utilizzare Java Enum valueOf, enum values, EnumSet e EnumMap con esempi.

Esempio Enum Java

La parola chiave enum Java viene utilizzata per creare un tipo enum. Diamo un’occhiata al programma di esempio di enum Java.

package com.journaldev.enums;

public enum ThreadStates {
	START,
	RUNNING,
	WAITING,
	DEAD;
}

Nell’esempio precedente, ThreadStates è l’enum con i campi costanti fissi START, RUNNING, WAITING e DEAD.

Enum Java vs Costanti

Adesso vediamo come l’enum Java sia migliore dei campi costanti normali nelle classi Java. Creiamo una classe costanti simile in Java.

package com.journaldev.enums;

public class ThreadStatesConstant {
	public static final int START = 1;
	public static final int WAITING = 2;
	public static final int RUNNING = 3;
	public static final int DEAD = 4;
}

Ora vediamo come vengono utilizzati sia l’enum che le costanti in un programma Java:

/**
* This method shows the benefit of using Enum over Constants
*/
private static void benefitsOfEnumOverConstants() {
	// I valori dell'Enum sono fissi
	simpleEnumExample(ThreadStates.START);
	simpleEnumExample(ThreadStates.WAITING);
	simpleEnumExample(ThreadStates.RUNNING);
	simpleEnumExample(ThreadStates.DEAD);
	simpleEnumExample(null);
		
	simpleConstantsExample(1);
	simpleConstantsExample(2);
	simpleConstantsExample(3);
	simpleConstantsExample(4);
	// possiamo passare qualsiasi costante int
	simpleConstantsExample(5);
}

private static void simpleEnumExample(ThreadStates th) {
	if(th == ThreadStates.START) System.out.println("Thread started");
	else if (th == ThreadStates.WAITING) System.out.println("Thread is waiting");
	else if (th == ThreadStates.RUNNING) System.out.println("Thread is running");
	else System.out.println("Thread is dead");
}
	
private static void simpleConstantsExample(int i) {
	if(i == ThreadStatesConstant.START) System.out.println("Thread started");
	else if (i == ThreadStatesConstant.WAITING) System.out.println("Thread is waiting");
	else if (i == ThreadStatesConstant.RUNNING) System.out.println("Thread is running");
	else System.out.println("Thread is dead");
}

Se guardiamo l’esempio sopra, ci sono due rischi nell’usare costanti che sono risolti dall’enum.

  1. Possiamo passare qualsiasi costante int al metodo simpleConstantsExample ma possiamo passare solo valori fissi a simpleEnumExample, quindi fornisce sicurezza di tipo.
  2. Possiamo cambiare il valore delle costanti int nella classe ThreadStatesConstant ma il programma sopra non genererà alcuna eccezione. Il nostro programma potrebbe non funzionare come previsto ma se cambiamo le costanti dell’enum, otterremo un errore di compilazione che elimina qualsiasi possibilità di problemi durante l’esecuzione.

Metodi Enum Java

Ora vediamo più caratteristiche dell’enum Java con un esempio.

package com.journaldev.enums;

import java.io.Closeable;
import java.io.IOException;

/**
 * This Enum example shows all the things we can do with Enum types
 *
 */
public enum ThreadStatesEnum implements Closeable{
	START(1){
		@Override
		public String toString(){
			return "START implementation. Priority="+getPriority();
		}

		@Override
		public String getDetail() {
			return "START";
		}
	},
	RUNNING(2){
		@Override
		public String getDetail() {
			return "RUNNING";
		}
	},
	WAITING(3){
		@Override
		public String getDetail() {
			return "WAITING";
		}
	},
	DEAD(4){
		@Override
		public String getDetail() {
			return "DEAD";
		}
	};
	
	private int priority;
	
	public abstract String getDetail();
	// I costruttori dell'Enum dovrebbero sempre essere privati.
	private ThreadStatesEnum(int i){
		priority = i;
	}
	
	// L'Enum può avere metodi
	public int getPriority(){
		return this.priority;
	}
	
	public void setPriority(int p){
		this.priority = p;
	}
	
	// L'Enum può sovrascrivere le funzioni
	@Override
	public String toString(){
		return "Default ThreadStatesConstructors implementation. Priority="+getPriority();
	}

	@Override
	public void close() throws IOException {
		System.out.println("Close of Enum");
	}
}

Punti Importanti dell’Enum Java

Di seguito sono riportati alcuni dei punti importanti per gli Enum in Java.

  1. Tutti gli enum di Java estendono implicitamente la classe java.lang.Enum che estende la classe Object e implementa le interfacce Serializable e Comparable. Quindi non è possibile estendere alcuna classe in un enum.
  2. Poiché enum è una parola chiave, non è possibile terminare il nome del pacchetto con essa, ad esempio com.journaldev.enum non è un nome di pacchetto valido.
  3. I enum possono implementare interfacce. Come nell’esempio di enum sopra, sta implementando l’interfaccia Closeable.
  4. I costruttori degli enum sono sempre privati.
  5. Non è possibile creare un’istanza di un enum utilizzando l’operatore new.
  6. Possiamo dichiarare metodi astratti in un enum di Java, quindi tutti i campi dell’enum devono implementare il metodo astratto. Nell’esempio sopra, getDetail() è il metodo astratto e tutti i campi dell’enum lo hanno implementato.
  7. Possiamo definire un metodo in un enum e i campi dell’enum possono sovrascriverlo. Ad esempio, il metodo toString() è definito nell’enum e il campo dell’enum START lo ha sovrascritto.
  8. I campi degli enum di Java hanno uno spazio dei nomi, possiamo utilizzare il campo dell’enum solo con il nome della classe come ThreadStates.START
  9. Gli enum possono essere utilizzati nell’istruzione switch, lo vedremo in azione nella parte successiva di questo tutorial.
  10. Possiamo estendere l’enum esistente senza rompere alcuna funzionalità esistente. Ad esempio, possiamo aggiungere un nuovo campo NEW nell’enum ThreadStates senza influenzare alcuna funzionalità esistente.
  11. Dato che i campi enum sono costanti, la pratica migliore in Java è scriverli in lettere maiuscole e usare il trattino basso per gli spazi. Ad esempio, EAST, WEST, EAST_DIRECTION ecc.
  12. Le costanti enum sono implicitamente statiche e finali
  13. Le costanti enum sono finali ma la loro variabile può ancora essere cambiata. Ad esempio, possiamo utilizzare il metodo setPriority() per cambiare la priorità delle costanti enum. Lo vedremo nell’esempio seguente.
  14. Dato che le costanti enum sono finali, possiamo confrontarle in modo sicuro usando i metodi “==” e equals(). Entrambi avranno lo stesso risultato.

Java EnumSet, EnumMap, valueOf()

Ora conosciamo la maggior parte delle caratteristiche dell’Enum, diamo un’occhiata a un esempio di programma Enum in Java. Poi impareremo altre caratteristiche di un enum.

package com.journaldev.enums;

import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;

public class JavaEnumExamples {

	public static void main(String[] args) throws IOException {
				
		usingEnumMethods();
		
		usingEnumValueOf();
		
		usingEnumValues();
		
		usingEnumInSwitch(ThreadStatesEnum.START);
		usingEnumInSwitch(ThreadStatesEnum.DEAD);
		
		usingEnumMap();
		
		usingEnumSet();
		
	}

	private static void usingEnumSet() {
		EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);
		for(ThreadStatesEnum tsenum : enumSet){
			System.out.println("Using EnumSet, priority = "+tsenum.getPriority());
		}
	}

	private static void usingEnumMap() {
		EnumMap<ThreadStatesEnum, String> enumMap = new EnumMap<ThreadStatesEnum,String>(ThreadStatesEnum.class);
		enumMap.put(ThreadStatesEnum.START, "Thread is started");
		enumMap.put(ThreadStatesEnum.RUNNING, "Thread is running");
		enumMap.put(ThreadStatesEnum.WAITING, "Thread is waiting");
		enumMap.put(ThreadStatesEnum.DEAD, "Thread is dead");
		
		Set keySet = enumMap.keySet();
		for(ThreadStatesEnum key : keySet){
			System.out.println("key="+key.toString()+":: value="+enumMap.get(key));
		}
		
	}

	private static void usingEnumInSwitch(ThreadStatesEnum th) {
		switch (th){
		case START:
			System.out.println("START thread");
			break;
		case WAITING:
			System.out.println("WAITING thread");
			break;
		case RUNNING:
			System.out.println("RUNNING thread");
			break;
		case DEAD:
			System.out.println("DEAD thread");
		}
	}

	private static void usingEnumValues() {
		ThreadStatesEnum[] thArray = ThreadStatesEnum.values();
		
		for(ThreadStatesEnum th : thArray){
			System.out.println(th.toString() + "::priority="+th.getPriority());
		}
	}

	private static void usingEnumValueOf() {
		ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class, "START");
		System.out.println("th priority="+th.getPriority());
	}

	private static void usingEnumMethods() throws IOException {
		ThreadStatesEnum thc = ThreadStatesEnum.DEAD;
		System.out.println("priority is:"+thc.getPriority());
		
		thc = ThreadStatesEnum.DEAD;
		System.out.println("Using overriden method."+thc.toString());
		
		thc = ThreadStatesEnum.START;
		System.out.println("Using overriden method."+thc.toString());
		thc.setPriority(10);
		System.out.println("Enum Constant variable changed priority value="+thc.getPriority());
		thc.close();
	}

}

Prima di spiegare altre importanti caratteristiche dell’enum, vediamo l’output del programma sopra.

priority is:4
Using overriden method.Default ThreadStatesConstructors implementation. Priority=4
Using overriden method.START implementation. Priority=1
Enum Constant variable changed priority value=10
Close of Enum
th priority=10
START implementation. Priority=10::priority=10
Default ThreadStatesConstructors implementation. Priority=2::priority=2
Default ThreadStatesConstructors implementation. Priority=3::priority=3
Default ThreadStatesConstructors implementation. Priority=4::priority=4
START thread
DEAD thread
key=START:: value=Thread is started
key=RUNNING:: value=Thread is running
key=WAITING:: value=Thread is waiting
key=DEAD:: value=Thread is dead
Using EnumSet, priority = 10
Using EnumSet, priority = 2
Using EnumSet, priority = 3
Using EnumSet, priority = 4

Punti importanti

  1. Il metodo usingEnumMethods() mostra come creare un oggetto enum e come utilizzarne i metodi. Mostra anche l’uso del metodo setPriority(int i) per modificare la variabile dell’enum.
  2. usingEnumValueOf() mostra l’uso di java.util.Enum valueOf(enumType, name) attraverso il quale possiamo creare un oggetto enum da una stringa. Solleva un’eccezione IllegalArgumentException se il tipo di enum specificato non ha una costante con il nome specificato, o l’oggetto della classe specificata non rappresenta un tipo di enum. Solleva anche una NullPointerException se uno degli argomenti è nullo.
  3. usingEnumValues() mostra l’uso del metodo values() che restituisce un array contenente tutti i valori dell’enum nell’ordine in cui sono dichiarati. Nota che questo metodo viene generato automaticamente dal compilatore Java per ogni enum. Non troverai l’implementazione di values() nella classe java.util.Enum.
  4. Il metodo usingEnumInSwitch() mostra come utilizzare le costanti enum in un caso di switch.
  5. usingEnumMap() mostra l’uso di java.util.EnumMap, introdotto nel framework delle collezioni di Java 1.5. EnumMap è un’implementazione di mappa per l’uso con chiavi di tipo enum. Tutte le chiavi in una mappa enum devono provenire da un singolo tipo di enum specificato, esplicitamente o implicitamente, durante la creazione della mappa. Non possiamo utilizzare null come chiave per EnumMap e EnumMap non è sincronizzato.
  6. usingEnumSet() il metodo mostra l’uso di java.util.EnumSet, che è un’implementazione di Set da utilizzare con i tipi di enum. Tutti gli elementi in un enum set devono provenire da un singolo tipo di enum specificato, esplicitamente o implicitamente, quando il set viene creato. EnumSet non è sincronizzato e non sono ammessi elementi nulli. Fornisce anche alcuni metodi utili come copyOf(Collection<E> c), of(E first, E... rest) e complementOf(EnumSet<E> s).

Puoi controllare tutti gli esempi nel nostro Repository GitHub.

Riferimento: Documentazione Oracle

Source:
https://www.digitalocean.com/community/tutorials/java-enum