Remplacer les Enums par des annotations énuméréesModifier la pagePage Historique

Aperçu

Les « constantes magiques » ou annotations de type sont de vieilles constantes Java ordinaires décorées d’une manière qui permet aux outils de les reconnaître comme des valeurs spéciales. Leur syntaxe n’est pas différente de celle de toute autre constante Java. Au lieu de cela, une annotation avec un nom facilement lisible qui liste toutes les constantes liées doit être créée.

Cette annotation peut ensuite décorer une valeur de retour ou un paramètre de méthode, donnant des indications aux outils que vous utilisez sur les valeurs qui sont acceptées ou peuvent être attendues. Leur principal objectif est d’appliquer la sécurité de type pour les paramètres de méthode et/ou les valeurs de retour de méthode tout en écrivant le code source.

Ceci est généralement utilisé pour remplacer les enums. Google décourage l’utilisation d’enums sur le développement d’applications Android, comme indiqué sur leurs directives pour les développeurs : « Les enums nécessitent souvent plus de deux fois plus de mémoire que les constantes statiques. Vous devriez strictement éviter d’utiliser les enums sur Android. »

IntDef

IntDef est une façon de remplacer une enum entière où il y a un paramètre qui ne devrait accepter que des valeurs int explicites. Par exemple, supposons que nous voulons enregistrer le type d’un élément d’alimentation comme indiqué ci-dessous:

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

À l’heure actuelle, il n’y a pas de validations pour s’assurer que le type passé dans le constructeur est valide. Nous pouvons utiliser IntDef pour nous assurer que la valeur est l’une des valeurs attendues en ajoutant des annotations:

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

Le même appel au constructeur du dernier exemple montrera maintenant une erreur dans Android Studio car maintenant il sait quelles valeurs attendre. Reportez-vous au guide officiel des annotations d’Android pour plus de détails.

StringDef

StringDef est de la même manière un moyen de remplacer une enum string où il y a un paramètre qui ne doit accepter que des valeurs explicites de chaîne. Par exemple, supposons que nous voulons enregistrer la valeur d’un paramètre comme indiqué ci-dessous:

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

À l’heure actuelle, il n’y a pas de validations pour s’assurer que le type passé dans le constructeur est valide. Nous pouvons utiliser StringDef pour nous assurer que la valeur est l’une des valeurs attendues en ajoutant des annotations:

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

Le même appel au constructeur du dernier exemple montrera maintenant une erreur dans Android Studio car maintenant il sait quelles valeurs attendre. Consultez le guide officiel des annotations Android pour plus de détails.