Erstatning af enumer med opregnede annotationerRedigér sideSideSidehistorik

Oversigt

“Magiske konstanter” eller typeannotationer er almindelige gamle Java-konstanter, der er dekoreret på en måde, så værktøjer kan genkende dem som særlige værdier. Deres syntaks er ikke forskellig fra enhver anden Java-konstant. I stedet skal der oprettes en annotation med et letlæseligt navn, som opregner alle relaterede konstanter.

Denne annotation kan derefter dekorere en returværdi eller en metodeparameter, hvilket giver de værktøjer, du bruger, hints om de værdier, der accepteres eller kan forventes. Deres hovedformål er at håndhæve typesikkerhed for metodeparametre og/eller metodeafkastværdier, mens man skriver kildekoden.

Dette bruges typisk til at erstatte enums. Google fraråder brugen af enums ved udvikling af Android-apps, som det fremgår af deres retningslinjer for udviklere: “Enums kræver ofte mere end dobbelt så meget hukommelse som statiske konstanter. Du bør strengt undgå at bruge enums på Android.”

IntDef

IntDef er en måde at erstatte en integer enum på, hvor der er en parameter, som kun bør acceptere eksplicitte int-værdier. Lad os f.eks. antage, at vi ønsker at registrere typen af et foderelement som vist nedenfor:

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

Ret nu er der ingen valideringer for at sikre, at den type, der er overgivet til konstruktøren, er gyldig. Vi kan bruge IntDef til at sikre, at værdien er en af de forventede værdier ved at tilføje 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; }}

Det samme konstruktorkald fra det sidste eksempel vil nu vise en fejl i Android Studio, fordi den nu ved, hvilke værdier den kan forvente. Se den officielle Android-annotationsvejledning for flere oplysninger.

StringDef

StringDef er på samme måde en måde at erstatte en string enum på, hvor der er en parameter, som kun skal acceptere eksplicitte stringværdier. Antag for eksempel, at vi ønsker at registrere værdien for en indstilling som vist nedenfor:

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

Ret nu er der ingen valideringer for at sikre, at den type, der er overgivet til konstruktøren, er gyldig. Vi kan bruge StringDef til at sikre, at værdien er en af de forventede værdier ved at tilføje 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; }}

Det samme konstruktorkald fra det sidste eksempel vil nu vise en fejl i Android Studio, fordi den nu ved, hvilke værdier den kan forvente. Se den officielle vejledning om Android-annotationer for at få flere oplysninger.