Ersetzen von Enums durch Enumerated AnnotationsBearbeiten SeiteSeite Historie

Übersicht

„Magische Konstanten“ oder Typ-Annotationen sind normale alte Java-Konstanten, die so dekoriert sind, dass Werkzeuge sie als spezielle Werte erkennen können. Ihre Syntax unterscheidet sich nicht von der jeder anderen Java-Konstante. Stattdessen muss eine Annotation mit einem leicht lesbaren Namen erstellt werden, die alle zugehörigen Konstanten auflistet.

Diese Annotation kann dann einen Rückgabewert oder einen Methodenparameter ausschmücken und den verwendeten Werkzeugen Hinweise darauf geben, welche Werte akzeptiert werden oder erwartet werden können. Ihr Hauptzweck ist es, Typsicherheit für Methodenparameter und/oder Methodenrückgabewerte beim Schreiben des Quellcodes zu erzwingen.

Dies wird typischerweise verwendet, um Enums zu ersetzen. Google rät von der Verwendung von Enums bei der Entwicklung von Android-Apps ab, wie in den Entwicklerrichtlinien angegeben: „Enums benötigen oft mehr als doppelt so viel Speicher wie statische Konstanten. Sie sollten die Verwendung von Enums unter Android strikt vermeiden.“

IntDef

IntDef ist eine Möglichkeit, eine Integer-Enum zu ersetzen, wenn es einen Parameter gibt, der nur explizite int-Werte akzeptieren soll. Nehmen wir zum Beispiel an, dass wir den Typ eines Futtermittels wie unten gezeigt aufzeichnen wollen:

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

Augenblicklich gibt es keine Validierung, um sicherzustellen, dass der an den Konstruktor übergebene Typ gültig ist. Wir können IntDef verwenden, um sicherzustellen, dass der Wert einer der erwarteten Werte ist, indem wir Anmerkungen hinzufügen:

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

Der gleiche Konstruktoraufruf aus dem letzten Beispiel zeigt nun einen Fehler in Android Studio an, da es nun weiß, welche Werte zu erwarten sind. Weitere Details finden Sie im offiziellen Android Annotations Guide.

StringDef

StringDef ist ebenfalls eine Möglichkeit, ein String-Enum zu ersetzen, wenn es einen Parameter gibt, der nur explizite String-Werte akzeptieren soll. Nehmen wir zum Beispiel an, wir wollen den Wert für eine Einstellung wie unten gezeigt aufzeichnen:

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

Im Moment gibt es keine Validierungen, um sicherzustellen, dass der Typ, der an den Konstruktor übergeben wird, gültig ist. Wir können StringDef verwenden, um sicherzustellen, dass der Wert einer der erwarteten Werte ist, indem wir Anmerkungen hinzufügen:

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

Der gleiche Konstruktoraufruf aus dem letzten Beispiel zeigt nun einen Fehler in Android Studio an, da es nun weiß, welche Werte zu erwarten sind. Weitere Details finden Sie im offiziellen Android Annotations Guide.