Reemplazando Enums con Anotaciones EnumeradasEditar PáginaHistoria

Resumen

Las «constantes mágicas» o anotaciones de tipo son viejas constantes Java regulares decoradas de una manera que permite a las herramientas reconocerlas como valores especiales. Su sintaxis no es diferente a la de cualquier otra constante de Java. En cambio, hay que crear una anotación con un nombre fácilmente legible que enumere todas las constantes relacionadas.

Esta anotación puede entonces decorar un valor de retorno o un parámetro de método, dando pistas a las herramientas que se utilizan sobre los valores que se aceptan o se pueden esperar. Su propósito principal es hacer cumplir la seguridad de tipo para los parámetros del método y/o los valores de retorno del método mientras se escribe el código fuente.

Esto se utiliza típicamente para reemplazar los enums. Google desaconseja el uso de enums en el desarrollo de aplicaciones para Android, como se indica en sus directrices para desarrolladores: «Los enums suelen requerir más del doble de memoria que las constantes estáticas. Deberías evitar estrictamente el uso de enums en Android»

IntDef

IntDef es una forma de reemplazar un enum de enteros donde hay un parámetro que sólo debe aceptar valores int explícitos. Por ejemplo, supongamos que queremos registrar el tipo de un elemento de alimentación como se muestra a continuación:

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; }}

Ahora mismo no hay validaciones para asegurar que el tipo pasado al constructor es válido. Podemos utilizar IntDef para asegurar que el valor es uno de los valores esperados añadiendo anotaciones:

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 misma llamada al constructor del último ejemplo mostrará ahora un error en Android Studio porque ahora sabe qué valores esperar. Consulte la guía oficial de anotaciones de Android para más detalles.

StringDef

StringDef es, de forma similar, una forma de reemplazar un enum de cadena donde hay un parámetro que sólo debe aceptar valores explícitos de cadena. Por ejemplo, supongamos que queremos registrar el valor de un ajuste como se muestra a continuación:

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; }}

Ahora mismo no hay validaciones para asegurar que el tipo pasado al constructor es válido. Podemos utilizar StringDef para asegurar que el valor es uno de los valores esperados añadiendo anotaciones:

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 misma llamada al constructor del último ejemplo mostrará ahora un error en Android Studio porque ahora sabe qué valores esperar. Consulte la guía oficial de anotaciones de Android para más detalles.