Replacing Enums with Enumerated AnnotationsEdit PagePage History

Overview

„Magiczne stałe” lub adnotacje typu to zwykłe stare stałe Javy udekorowane w sposób, który pozwala narzędziom rozpoznawać je jako wartości specjalne. Ich składnia nie różni się od każdej innej stałej Javy. Zamiast tego należy utworzyć adnotację z łatwą do odczytania nazwą, która wymienia wszystkie powiązane stałe.

Ta adnotacja może następnie ozdobić wartość zwracaną lub parametr metody, dając podpowiedzi narzędziom, których używasz, o wartościach, które są akceptowane lub mogą być oczekiwane. Ich głównym celem jest wymuszenie bezpieczeństwa typu dla parametrów metod i / lub wartości zwrotnych metod podczas pisania kodu źródłowego.

To jest zwykle używane do zastąpienia enums. Google zniechęca do korzystania z enumów w rozwoju aplikacji na Androida, jak stwierdzono na ich wytycznych dla programistów: „Enumy często wymagają więcej niż dwa razy więcej pamięci niż statyczne stałe. Powinieneś unikać używania enum na Androidzie.”

IntDef

IntDef jest sposobem na zastąpienie enum integer gdzie jest parametr, który powinien akceptować tylko jawne wartości int. Na przykład, załóżmy, że chcemy zapisać typ elementu feed, jak pokazano poniżej:

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

Teraz nie ma walidacji, aby zapewnić, że typ przekazany do konstruktora jest poprawny. Możemy użyć IntDef, aby zapewnić, że wartość jest jedną z oczekiwanych wartości poprzez dodanie adnotacji:

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

Ten sam konstruktor z ostatniego przykładu pokaże teraz błąd w Android Studio, ponieważ teraz wie, jakich wartości oczekiwać. Odnieś się do oficjalnego przewodnika po adnotacjach Androida po więcej szczegółów.

StringDef

StringDef jest podobnie sposobem na zastąpienie enum łańcuchowego, gdzie jest parametr, który powinien akceptować tylko jawne wartości łańcuchowe. Na przykład, załóżmy, że chcemy zapisać wartość dla ustawienia, jak pokazano poniżej:

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

Teraz nie ma walidacji, aby zapewnić, że typ przekazany do konstruktora jest poprawny. Możemy użyć StringDef, aby zapewnić, że wartość jest jedną z oczekiwanych wartości poprzez dodanie adnotacji:

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

Ten sam konstruktor wywołany w ostatnim przykładzie pokaże teraz błąd w Android Studio, ponieważ teraz wie, jakich wartości oczekiwać. Odnieś się do oficjalnego przewodnika po adnotacjach Androida, aby uzyskać więcej szczegółów.