Sostituzione di Enum con Annotazioni EnumerateModifica PaginaPagina Storia

Panoramica

Le “costanti magiche” o annotazioni di tipo sono normali vecchie costanti Java decorate in un modo che permette agli strumenti di riconoscerle come valori speciali. La loro sintassi non è diversa da quella di qualsiasi altra costante Java. Invece, deve essere creata un’annotazione con un nome facilmente leggibile che elenca tutte le costanti correlate.

Questa annotazione può quindi decorare un valore di ritorno o un parametro di metodo, dando suggerimenti agli strumenti che usate sui valori che sono accettati o che possono essere previsti. Il loro scopo principale è quello di applicare la sicurezza dei tipi per i parametri dei metodi e/o i valori di ritorno dei metodi mentre si scrive il codice sorgente.

Questo è tipicamente usato per sostituire gli enum. Google scoraggia l’uso degli enum nello sviluppo di applicazioni Android, come dichiarato nelle loro linee guida per gli sviluppatori: “Gli enum spesso richiedono più del doppio della memoria delle costanti statiche. Dovresti rigorosamente evitare di usare gli enum su Android.”

IntDef

IntDef è un modo di sostituire un enum intero dove c’è un parametro che dovrebbe accettare solo valori int espliciti. Per esempio, supponiamo di voler registrare il tipo di un elemento del feed come mostrato qui sotto:

public class ItemTypeDescriptor { public static final int TYPE_MUSIC = 0; public static final int TYPE_PHOTO = 1; public static final int TYPE_TEXT = 2; public final int itemType; public ItemTypeDescriptor(int itemType) { this.itemType = itemType; }}

In questo momento non ci sono validazioni per assicurare che il tipo passato nel costruttore sia valido. Possiamo usare IntDef per assicurarci che il valore sia uno dei valori previsti aggiungendo le annotazioni:

public class ItemTypeDescriptor { // ... type definitions // Describes when the annotation will be discarded @Retention(RetentionPolicy.SOURCE) // Enumerate valid values for this interface @IntDef({TYPE_MUSIC, TYPE_PHOTO, TYPE_TEXT}) // Create an interface for validating int types public @interface ItemTypeDef {} // Declare the constants public static final int TYPE_MUSIC = 0; public static final int TYPE_PHOTO = 1; public static final int TYPE_TEXT = 2; // Mark the argument as restricted to these enumerated types public ItemTypeDescriptor(@ItemTypeDef int itemType) { this.itemType = itemType; }}

La stessa chiamata al costruttore dell’ultimo esempio ora mostrerà un errore in Android Studio perché ora sa quali valori aspettarsi. Fate riferimento alla guida ufficiale alle annotazioni di Android per maggiori dettagli.

StringDef

StringDef è similmente un modo di sostituire un enum di stringhe dove c’è un parametro che dovrebbe accettare solo valori di stringa espliciti. Per esempio, supponiamo di voler registrare il valore di un’impostazione come mostrato qui sotto:

public class FilterColorDescriptor { public static final String FILTER_BLUE = "blue"; public static final String FILTER_RED = "red"; public static final String FILTER_GRAY = "gray"; public final String filterColor; public FilterColorDescriptor(String filterColor) { this.filterColor = filterColor; }}

In questo momento non c’è nessuna validazione per assicurare che il tipo passato nel costruttore sia valido. Possiamo usare StringDef per assicurarci che il valore sia uno dei valori previsti aggiungendo le annotazioni:

public class FilterColorDescriptor { // ... type definitions // Describes when the annotation will be discarded @Retention(RetentionPolicy.SOURCE) // Enumerate valid values for this interface @StringDef({FILTER_BLUE, FILTER_RED, FILTER_GRAY}) // Create an interface for validating String types public @interface FilterColorDef {} // Declare the constants public static final String FILTER_BLUE = "blue"; public static final String FILTER_RED = "red"; public static final String FILTER_GRAY = "gray"; // Mark the argument as restricted to these enumerated types public FilterColorDescriptor(@FilterColorDef String filterColor) { this.filterColor = filterColor; }}

La stessa chiamata al costruttore dell’ultimo esempio ora mostrerà un errore in Android Studio perché ora sa quali valori aspettarsi. Fate riferimento alla guida ufficiale alle annotazioni di Android per maggiori dettagli.