2008-09-18 5 views
11

Wenn eine Klasse eine Anmerkung definiert hat, ist es irgendwie möglich, ihre Unterklasse zu zwingen, die gleiche Anmerkung zu definieren?Wie erzwinge ich eine Java-Unterklasse, um eine Anmerkung zu definieren?

Zum Beispiel haben wir ein einfaches Klasse/Unterklasse-Paar, das die @Author @interface. Was teilt ich mag ist, jede weitere Unterklasse zwingen, dasselbe tun @Author Anmerkung zu definieren, ein RuntimeException irgendwo auf der Straße zu verhindern.

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

Ich weiß, dass ich alle Anmerkungen zur Laufzeit und prüfen, ob die fehlenden @Author aufzählen kann, aber ich würde wirklich gerne tun Dies zur Zeit der Kompilierung, wenn möglich.

Antwort

3

Ich bin mir ziemlich sicher, dass dies zur Kompilierzeit nicht möglich ist.

Dies ist jedoch eine offensichtliche Aufgabe für einen "Einheit" -Test. Wenn Sie solche Konventionen haben, die Sie durchsetzen möchten, die aber mit dem Compiler nur schwer oder gar nicht überprüft werden können, sind "unit" -Tests eine einfache Möglichkeit, sie zu überprüfen.

Eine andere Möglichkeit ist die Implementierung einer benutzerdefinierten Regel in einem statischen Analysator. Auch hier gibt es viele Möglichkeiten.

(Ich stelle Einheit in Angst-Anführungszeichen, da dies wirklich ein Test der Konventionen ist, anstatt einer bestimmten Einheit. Aber es sollte zusammen mit Ihren Komponententests laufen).

2

Sie könnten eine Annotation (z. B. @EnforceAuthor) mit @Inherited für die Superklasse erstellen und Compiler-Annotationen (seit Java 1.6) verwenden, um die Kompilierzeit nachzuholen. Dann haben Sie einen Verweis auf die Unterklasse und können prüfen, ob eine andere Annotation (z. B. @Author) fehlt. Dies würde erlauben, das Kompilieren mit einer Fehlermeldung abzubrechen.