> For the complete documentation index, see [llms.txt](https://checksound.gitbook.io/corsojava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://checksound.gitbook.io/corsojava/enum.md).

# Enum

Finora abbiamo visto come titi di dati, i tipi primitivi (**int**, **double**, **boolean**, **char** ......), i tipi da noi definito tramite la definizione di classi (tipi reference) con cui possiamo estendere i tipi di dati oltre quelli primitivi: definiamo ad esempio una classe `Persona` con due attributi `nome` di tipo *String* ed `eta` di tipo *int*. Questo è un nuovo tipo di dati oltre a quelli primitivi.

Ora vediamo un nuovo tipo di dato anche questo di tipo reference, il tipo **enum**, che permette di definire un tipo che può avere solo un certo numero di possibili valori (costanti), stabiliti nella definizione del tipo, ad esempio i giorni della settimana, i mesi dell'anno o altre costanti che molto spesso sono utili quando si programma. Vedi per trattazione argomento *Enum*: <http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaEnum.html>

### NOTA

I tipi enum sono stati introdotti in Java SE versione 5.0 (anno 2004) quando la prima versione di Java (1.0) è del 1996. Nella api di alcune classi precedenti alla 5.0 si vede come venivano definite delle costanti non avendo la possibilità definirle come `enum`, e così sono rimaste per retro compatibilità con le vecchie versioni di Java: le constanti venivano definiti come attributi `public static final int <NOME_COSTANTE> = <INT_VALUE>`&#x20;

Ad esempio per la classe `java.util.Calendar` <https://docs.oracle.com/javase/7/docs/api/constant-values.html#java.util.Calendar> classe per lavorare con le date definisce molte costanti. Vediamo un esempio di utilizzo e quali potrebbero essere i problemi che hanno portato all'inserimento dei tipi enum in java.

Vediamo l'esempio:&#x20;

```java
package esempio;

import java.util.Calendar;

public class TestCalendar {

	public static void main(String[] args) {
		Calendar rightNow = Calendar.getInstance();
		
		int mounthNumber = rightNow.get(Calendar.MONTH);
		
		System.out.println("Mounth number: " + mounthNumber);
		
		// the same as Calendar.MONTH
		mounthNumber = rightNow.get(2);
		
		System.out.println("Mounth number: " + mounthNumber);
		
		// compile time no problem ma eccezione java.lang.ArrayIndexOutOfBoundsException 
		// in esecuzione
		int value = rightNow.get(20);
		
		
	}

}

```

Si vede nell'esempio che il fatto di non avere l'enum e quindi di simulare le costanti con variabili `static final` non permette controlli in fase di compilazione come si avrebbero se si utilizzassero i tipi enum.&#x20;

Eseguendo il programma ho il seguente errore in output:

```
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
	at java.util.Calendar.internalGet(Calendar.java:1840)
	at java.util.Calendar.get(Calendar.java:1827)
	at esempio.TestCalendar.main(TestCalendar.java:18)

```

in quanto il valore *20* come parametro del metodo `get()` di `Calendar` non è tra quelli ammessi.

Le nuove classi per lavorare con le date e tempo sotto `java.time` invece utilizzano i tipi enumerativi (**enum**).&#x20;

Esempio con le nuove classi di Java che utilizzano come parametri il tipo enum [java.time.Month](https://docs.oracle.com/javase/8/docs/api/java/time/Month.html)

```java
package esempio;

import java.time.LocalDate;
import java.time.Month;

public class TestLocalDate {

	public static void main(String[] args) {
		LocalDate dateOfBirth = LocalDate.of(2012, Month.MAY, 14);
		LocalDate firstBirthday = dateOfBirth.plusYears(1);
		
		System.out.println("FirstBithday: " + firstBirthday);
	}

}
```

### ESEMPI

Vedi esempi di enum: <https://github.com/checksound/LezioneEnum>&#x20;

### SUMMARY

Quando si possono usare **enums**? Ogni volta che abbiamo bisogno di un numero fisso di costanti, il cui valore è noto al tempo di compilazione (*compile-time*). Questi includono i tipi enumerativi naturali (come i giorni della settimana o i semi delle carte) o altri tipi di insiemi i cui valori sono conosciuti a priori (a compile-time) come la scelta di un menù di una GUI, i flag di un'interfaccia a riga di comando etc..&#x20;

Proprietà del tipo enum:

1. Enums sono type-safe (il controllo sulla validità del valore è eseguito in fase di compilazione);
2. Enums creano il proprio namespace (esempio `Stagione.ESTATE` o `Stagione.AUTUNNO` se ho definito un `enum Stagione { ESTATE, AUTUNNO, INVERNO, PRIMAVERA, ESTATE }`;
3. Quando un `enum` è definito, una classe che estende `java.lang.Enum` è creata. Quindi un `enum` non può estendere un altro `enum` o una classe.  Inoltre il compilatore crea una istanza della classe per ogni costante definita in `enum`. La classe `java.lang.Enum` ha questi metodi:&#x20;

   ```java
   public final String name();  // Returns the name of this enum constant, exactly as declared in its enum declaration.
                                // You could also override the toString() to provide a more user-friendly description.
   public String toString();    // Returns the name of this enum constant, as contained in the declaration.
                                // This method may be overridden.
   public final int ordinal();  // Returns the ordinal of this enumeration constant.
   ```
4. Tutte le costanti definite in un enum sono `public static final`. Poiché sono `static` possono essere accedute tramite  *`EnumName.instanceName`*.
5. Non si istanzia un `enum`, ma utilizzano le costanti definite;
6. Enums possono essere utilizzati negli statement di `switch` esattamente come i tipi `int`;
