Erreur lors de la définition d'une valeur null par défaut pour une annotation du champ
Pourquoi j'obtiens un message d'erreur "valeur de l'Attribut doit être constant". N'est-ce pas null constante???
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SomeInterface {
Class<? extends Foo> bar() default null;//this doesn't compile
}
- Pourquoi quelqu'un aurait besoin de ceci (à la compilation ou de contournement)? Le même "fonctionnalité" est déjà accordée par
Class<? extends Foo> bar();
.
Vous devez vous connecter pour publier un commentaire.
Je ne sais pas pourquoi, mais le JLS est très clair:
Et la définition d'un élément par défaut est:
Malheureusement, je continue de trouver que les nouvelles fonctionnalités du langage (Énumérations, et maintenant les Annotations) ont très peu serviable messages d'erreur du compilateur lorsque vous ne respectez pas la langue spec.
EDIT: UN peu googleing trouvé le la suite dans la JSR-308, où ils font valoir pour autoriser les valeurs null dans cette situation:
Je pense que les deux derniers points sont pertinents à "pourquoi ne pas le faire en premier lieu." Le dernier point apporte certainement un bon point - un processeur d'annotation n'a jamais à être concernés qu'ils obtiendront une valeur null sur une annotation de la valeur. J'ai tendance à voir qu'à mesure que le travail d'annotation des transformateurs et d'autres cadre de ce type de code pour faire ce genre de vérifier les développeurs de code plus clair plutôt que l'inverse, mais il serait certainement difficile de justifier le changement.
Essayer cette
Il ne nécessite pas une nouvelle classe et c'est déjà un mot-clé en Java qui ne signifie rien.
Class<? extends Foo> bar() default void.null
ne compile pas.Il semblerait que c'est illégal, bien que la JLS est très floue sur ce point.
J'ai secoué ma mémoire pour essayer de penser à une annotation existante qui a un attribut de Classe à une annotation, et le souvenir de celui de l'API JAXB:
Vous pouvez voir comment ils ont eu à définir un mannequin de classe statique pour contenir l'équivalent d'une valeur null.
Désagréable.
Il semble il y a un autre moyen de le faire.
Je n'aime pas cela, mais cela pourrait fonctionner.
Donc, fondamentalement, vous créez un Tableau vide à la place. Cela semble permettre à une valeur par défaut.
Comme mentionné précédemment, le langage Java, les spécifications ne pas autoriser les valeurs null dans les annotations par défaut.
Ce que j'ai tendance à faire est de définir
DEFAULT_VALUE
constantes dans le haut de l'annotation définition. Quelque chose comme:Ensuite dans mon code je fais quelque chose comme:
Dans votre cas, avec une classe, je voudrais juste définir un marqueur de classe. Malheureusement, vous ne pouvez pas avoir une constante pour cela vous devez faire quelque chose comme:
Votre
DefaultFoo
catégorie, juste un vide de mise en œuvre, de sorte que le code peut faire:Espère que cette aide.
Que le message d'erreur est trompeur, mais, non, la
null
littérale n'est pas une expression constante, tel que défini dans le Langage Java Specification, ici.En outre, la Java Langage De Spécification dit
Et à expliquer ce que cela signifie
Donc, ici, votre type d'élément, les
Class<? extends Foo>
, n'est pas en proportion avec la valeur par défaut, parce que la valeur estnull
.or
et un intérieurand
, qui ne peut pas être laissé de côté.Comme d'autres l'ont dit, il y a une règle qui dit que nul n'est pas une valeur par défaut en Java.
Si vous avez un nombre limité de valeurs possibles que le champ peut avoir, puis une option pour contourner cela est de faire le type de champ personnalisé enum qui lui-même contient une cartographie de la valeur null. Par exemple, imaginez que j'ai l'annotation suivante que je veux un null par défaut pour:
Comme nous l'avons établi, ce n'est pas autorisé. Ce que nous pouvons faire au lieu de se définir un enum:
et de modifier l'annotation en tant que tel:
Le principal inconvénient de cette (apartés d'avoir à énumérer vos valeurs possibles), c'est que vous avez emballé votre valeur dans un enum, de sorte que vous aurez besoin d'invoquer la propriété/getter sur l'enum pour obtenir la valeur.