Come faccio a forzare una sottoclasse di Java per definire un'Annotazione?
-
01-07-2019 - |
Domanda
Se una classe definita un'annotazione, è in qualche modo possibile forzare la sua sottoclasse di definire la stessa annotazione?
Per esempio, abbiamo una semplice classe/sottoclasse coppia che condividono la @Author @interface.
Quello che vorrei fare è la forza di ogni ulteriore sottoclasse di definire la stessa @Author
l'annotazione, la prevenzione di un RuntimeException
da qualche parte lungo la strada.
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 {}
So che posso enumerare tutte le annotazioni in fase di esecuzione e di controllo per l'mancanti @Author
, ma mi piacerebbe molto fare questo a tempo di compilazione, se possibile.
Soluzione
Si può fare con JSR 269, in fase di compilazione.Vedere : http://today.java.net/pub/a/today/2006/06/29/validate-java-ee-annotations-with-annotation-processors.html#pluggable-annotation-processing-api
Altri suggerimenti
Io sono abbastanza sicuro che questo è impossibile da fare in fase di compilazione.
Tuttavia, questo è un evidente compito di "unità"-test.Se si dispone di convegni come questo che vuoi imposto, ma che può essere difficile o impossibile da controllare con il compilatore, "l'unità"-i test sono un modo semplice per controllare di loro.
Un'altra possibilità è quella di implementare una regola personalizzata in un analizzatore statico.Ci sono molte opzioni, anche qui.
(Ho messo unità di spaventare le virgolette, dato che questa è davvero una prova di convenzioni, piuttosto che di una specifica unità.Ma dovrebbe funzionare insieme con l'unità-test).
Si potrebbe fare un'Annotazione (ad es.@EnforceAuthor) con @Ereditato la superclasse e utilizzare il compilatore annotazioni (dato che Java 1.6) per recuperare in fase di compilazione.Quindi avere un riferimento per la sottoclasse e possibile verificare se un'altra Annotazione (ad es.@Autore)) è mancante.Questo permetterebbe di annullare la compilazione con un messaggio di errore.