Ersättning av enum med uppräknade anteckningarRedigera sidaSidaSida Historik

Översikt

”Magiska konstanter” eller typannotationer är vanliga gamla Java-konstanter som är dekorerade på ett sätt som gör att verktygen kan känna igen dem som speciella värden. Deras syntax skiljer sig inte från någon annan Java-konstant. Istället måste en annotation med ett lättläst namn som listar alla relaterade konstanter skapas.

Denna annotation kan sedan dekorera ett returvärde eller en metodparameter och ge tips till de verktyg du använder om vilka värden som accepteras eller kan förväntas. Deras huvudsyfte är att genomdriva typsäkerhet för metodparametrar och/eller metodreturvärden när man skriver källkoden.

Detta används vanligtvis för att ersätta enums. Google avråder från att använda enums vid utveckling av Android-appar, vilket anges i deras riktlinjer för utvecklare: ”Enums kräver ofta mer än dubbelt så mycket minne som statiska konstanter. Du bör strikt undvika att använda enums på Android.”

IntDef

IntDef är ett sätt att ersätta en enum för heltal där det finns en parameter som endast ska acceptera explicita int-värden. Anta till exempel att vi vill registrera typen av ett foderobjekt enligt nedan:

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

Redan nu finns det inga valideringar för att se till att den typ som skickas in i konstruktören är giltig. Vi kan använda IntDef för att säkerställa att värdet är ett av de förväntade värdena genom att lägga till annotationer:

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

Samma konstruktorkallelse som i det senaste exemplet kommer nu att visa ett fel i Android Studio eftersom den nu vet vilka värden den ska förvänta sig. Se den officiella guiden för Android-annotationer för mer information.

StringDef

StringDef är på samma sätt ett sätt att ersätta en string enum där det finns en parameter som endast ska acceptera explicita strängvärden. Anta till exempel att vi vill registrera värdet för en inställning enligt nedan:

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

Redan nu finns det inga valideringar för att säkerställa att den typ som skickas in i konstruktören är giltig. Vi kan använda StringDef för att säkerställa att värdet är ett av de förväntade värdena genom att lägga till annotationer:

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

Samma konstruktorkallelse från det senaste exemplet kommer nu att visa ett fel i Android Studio eftersom den nu vet vilka värden den kan förvänta sig. Se den officiella guiden för Android-annotationer för mer information.