2008-09-18 21 views
11

Si une classe définit une annotation, est-il possible de forcer sa sous-classe à définir la même annotation?Comment forcer une sous-classe Java à définir une annotation?

Par exemple, nous avons une simple paire classe/sous-classe qui partagent la @Author @interface. Ce que je voudrais faire est la force chaque sous-classe plus pour définir la même annotation @Author, ce qui empêche une RuntimeException quelque part sur la route.

TestClass.java:

import java.lang.annotation.*; 

@Retention(RetentionPolicy.RUNTIME) 
@interface Author { String name(); } 

@Author(name = "foo") 
public abstract class TestClass 
{ 
    public static String getInfo(Class<? extends TestClass> c) 
    { 
     return c.getAnnotation(Author.class).name(); 
    } 

    public static void main(String[] args) 
    { 
     System.out.println("The test class was written by " 
         + getInfo(TestClass.class)); 
     System.out.println("The test subclass was written by " 
         + getInfo(TestSubClass.class)); 
    } 
} 

TestSubClass.java:

@Author(name = "bar") 
public abstract class TestSubClass extends TestClass {} 

Je sais que je peux énumérer toutes les annotations à l'exécution et vérifiez les disparus @Author, mais je voudrais vraiment faire ceci au moment de la compilation, si possible.

Répondre

3

Je suis tout à fait sûr que c'est impossible à faire au moment de la compilation.

Cependant, ceci est une tâche évidente pour un test "d'unité". Si vous avez des conventions de ce type que vous aimeriez appliquer, mais qui peuvent être difficiles ou impossibles à vérifier avec le compilateur, les tests unitaires sont un moyen simple de les vérifier.

Une autre possibilité consiste à implémenter une règle personnalisée dans un analyseur statique. Il y a beaucoup d'options ici aussi.

(Je mets l'unité dans des guillemets, car c'est vraiment un test de conventions, plutôt que d'une unité spécifique, mais elle devrait fonctionner avec vos tests unitaires).

2

Vous pouvez créer une annotation (par exemple, @EnforceAuthor) avec @Inherited sur la superclasse et utiliser les annotations du compilateur (depuis Java 1.6) pour rattraper le retard lors de la compilation. Ensuite, vous avez une référence à la sous-classe et pouvez vérifier si une autre annotation (par exemple @Author)) est manquante. Cela permettrait d'annuler la compilation avec un message d'erreur.