Nahrazení enumů vyjmenovanými anotacemiUpravit stránkuHistorie stránek

Přehled

„Magické konstanty“ nebo typové anotace jsou obyčejné staré konstanty Javy upravené způsobem, který umožňuje nástrojům rozpoznat je jako speciální hodnoty. Jejich syntaxe se neliší od jiných konstant jazyka Java. Místo toho je třeba vytvořit anotaci se snadno čitelným názvem, která obsahuje seznam všech souvisejících konstant.

Tato anotace pak může zdobit návratovou hodnotu nebo parametr metody a napovídat používaným nástrojům, jaké hodnoty jsou akceptovány nebo jaké lze očekávat. Jejich hlavním účelem je vynutit typovou bezpečnost pro parametry metod a/nebo návratové hodnoty metod při psaní zdrojového kódu.

Obvykle se používají k nahrazení enumů. Společnost Google nedoporučuje používat enumy při vývoji aplikací pro systém Android, jak je uvedeno v jejích pokynech pro vývojáře: „Enumy často vyžadují více než dvakrát tolik paměti než statické konstanty. Měli byste se striktně vyhnout používání enumů v systému Android.“

IntDef

IntDef je způsob nahrazení celočíselného enumu, kde je parametr, který by měl přijímat pouze explicitní hodnoty int. Předpokládejme například, že chceme zaznamenat typ položky krmiva, jak je uvedeno níže:

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

Právě teď neexistuje žádná validace, která by zajistila, že typ předaný do konstruktoru je platný. Můžeme použít IntDef, abychom zajistili, že hodnota je jednou z očekávaných hodnot přidáním anotací:

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

Stejné volání konstruktoru z minulého příkladu nyní v aplikaci Android Studio zobrazí chybu, protože nyní ví, jaké hodnoty má očekávat. Další podrobnosti najdete v oficiálním průvodci anotacemi systému Android.

StringDef

StringDef je podobně způsob, jak nahradit řetězcový výčet, kde je parametr, který by měl přijímat pouze explicitní řetězcové hodnoty. Předpokládejme například, že chceme zaznamenat hodnotu pro nastavení, jak je uvedeno níže:

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

Právě nyní neexistuje žádná validace, která by zajistila, že typ předávaný do konstruktoru je platný. Můžeme použít StringDef, abychom zajistili, že hodnota je jednou z očekávaných hodnot přidáním anotací:

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

Stejné volání konstruktoru z minulého příkladu nyní v aplikaci Android Studio zobrazí chybu, protože nyní ví, jaké hodnoty má očekávat. Další podrobnosti najdete v oficiálním průvodci anotacemi systému Android.