Ich verstehe nicht, warum Java-Annotationen keine Vererbung enthalten, genau wie Java-Klassen. Ich denke, es wäre sehr nützlich.
Zum Beispiel: Ich möchte wissen, ob eine bestimmte Anmerkung ein Validator ist. Mit der Vererbung konnte ich reflexartig durch Superklassen navigieren, um zu wissen, ob diese Annotation a erweitert ValidatorAnnotation
. Wie kann ich das sonst erreichen?
Kann mir jemand einen Grund für diese Designentscheidung geben?
java
inheritance
annotations
Sinuhepop
quelle
quelle
java.lang.annotation.Annotation
, dh jede Annotation istinstanceof
es, obwohl diese Tatsache nicht explizit deklariert ist.Antworten:
Über den Grund, warum es nicht so entworfen wurde, finden Sie die Antwort in den JSR 175 Design FAQ, wo es heißt:
Also, ja, ich denke, der Grund ist, dass es nur KISS ist. Wie auch immer, es scheint, dass dieses Problem (zusammen mit vielen anderen) als Teil von JSR 308 untersucht wird , und Sie können sogar einen alternativen Compiler mit dieser Funktionalität finden, die bereits von Mathias Ricken entwickelt wurde .
quelle
Erweiterbare Anmerkungen würden die Belastung durch die Angabe und Wartung eines anderen Typsystems effektiv erhöhen. Und dies wäre ein ziemlich einzigartiges Typsystem, so dass Sie nicht einfach ein OO-Typ-Paradigma anwenden könnten.
Denken Sie über alle Probleme nach, wenn Sie Polymorphismus und Vererbung in eine Annotation einführen (z. B. was passiert, wenn die Sub-Annotation Meta-Annotation-Spezifikationen wie die Aufbewahrung ändert?).
Und all diese zusätzliche Komplexität für welchen Anwendungsfall?
Sie möchten wissen, ob eine bestimmte Anmerkung zu einer Kategorie gehört?
Versuche dies:
Wie Sie sehen, können Sie mithilfe der bereitgestellten Funktionen problemlos Anmerkungen ohne übermäßige Schmerzen gruppieren und kategorisieren.
Also, KISS ist der Grund für ein Meta-Typ - Typ - System auf die Java - Sprache einzuführen.
[ps edit]
Ich habe den String nur zur Demonstration und im Hinblick auf eine offene Meta-Annotation verwendet. Für Ihr eigenes Projekt können Sie natürlich eine Aufzählung von Kategorietypen verwenden und für eine bestimmte Anmerkung mehrere Kategorien ("Mehrfachvererbung") angeben. Beachten Sie, dass die Werte völlig falsch sind und nur zu Demonstrationszwecken dienen:
quelle
@Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @interface C {}; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @C public @interface F {} class a{ @F public void S() {} } @Test public void blahTest() throws NoSuchMethodException { Method m = a.class.getMethod("S"); System.out.println(m.isAnnotationPresent(C.class)); }
In gewisser Weise haben Sie es bereits mit Anmerkungen - Meta-Anmerkungen. Wenn Sie eine Annotation mit Metainformationen versehen, entspricht dies in vielerlei Hinsicht der Erweiterung einer zusätzlichen Schnittstelle. Anmerkungen sind Schnittstellen, sodass Polymorphismus nicht wirklich ins Spiel kommt. Da sie statischer Natur sind, kann es kein dynamisches Laufzeit-Dispatching geben.
In Ihrem Validator-Beispiel können Sie einfach in der Annotation den kommentierten Typ abrufen und prüfen, ob er eine Validator-Meta-Annotation enthält.
Der einzige Anwendungsfall, den ich sehen konnte, dass Vererbung helfen würde, ist, wenn Sie in der Lage sein möchten, die Annotation nach Supertyp zu erhalten, aber dies würde eine ganze Reihe von Komplexität hinzufügen, da eine bestimmte Methode oder ein bestimmter Typ möglicherweise zwei solche Annotationen enthält. Dies bedeutet, dass ein Array anstelle nur eines einzelnen Objekts zurückgegeben werden muss.
Daher denke ich, dass die ultimative Antwort darin besteht, dass die Anwendungsfälle esoterisch sind und mehr Standardanwendungsfälle komplizieren, sodass es sich nicht lohnt.
quelle
Die Entwickler der Java-Annotationsunterstützung haben eine Reihe von "Vereinfachungen" zum Nachteil der Java-Community vorgenommen.
Keine Annotationen-Subtypen machen viele komplexe Annotationen unnötig hässlich. Man kann nicht einfach ein Attribut in einer Annotation haben, das eines von drei Dingen enthalten kann. Man muss drei separate Attribute haben, was Entwickler verwirrt und eine Laufzeitvalidierung erfordert, um sicherzustellen, dass nur eines der drei verwendet wird.
Nur eine Anmerkung eines bestimmten Typs pro Site. Dies hat zu einem völlig unnötigen Anmerkungsmuster für Sammlungen geführt. @Validation und @Validations, @Image und @Images usw.
Das zweite Problem wird in Java 8 behoben, aber es ist zu spät. Viele Frameworks wurden basierend auf dem geschrieben, was in Java 5 möglich war, und jetzt sind diese API-Warzen für eine lange Zeit hier.
quelle
Ich könnte drei Jahre zu spät auf diese Frage antworten, aber ich fand es interessant, weil ich mich an derselben Stelle befand. Hier ist meine Meinung dazu. Sie können Anmerkungen als Aufzählungen anzeigen. Sie bieten eine einseitige Art von Informationen - verwenden Sie sie oder verlieren Sie sie.
Ich hatte eine Situation, in der ich GET, POST, PUT und DELETE in einer Web-App simulieren wollte. Ich wollte unbedingt eine "super" Annotation mit dem Namen "HTTP_METHOD" haben. Später wurde mir klar, dass es keine Rolle spielte. Nun, ich musste mich damit abfinden, ein verstecktes Feld im HTML-Formular zu verwenden, um DELETE und PUT zu identifizieren (da POST und GET sowieso verfügbar waren).
Auf der Serverseite habe ich nach einem versteckten Anforderungsparameter mit dem Namen "_method" gesucht. Wenn der Wert PUT oder DELETE war, wurde die zugehörige HTTP-Anforderungsmethode überschrieben. Trotzdem war es egal, ob ich eine Anmerkung erweitern musste oder nicht, um die Arbeit zu erledigen. Alle Anmerkungen sahen gleich aus, wurden jedoch auf der Serverseite unterschiedlich behandelt.
Lassen Sie in Ihrem Fall den Juckreiz fallen, um Anmerkungen zu erweitern. Behandle sie als "Marker". Sie "repräsentieren" einige Informationen und "manipulieren" nicht unbedingt einige Informationen.
quelle
Eine Sache, an die ich denken könnte, ist die Möglichkeit, mehrere Anmerkungen zu haben. Sie können also an derselben Stelle einen Validator und eine spezifischere Anmerkung hinzufügen. Aber ich könnte mich irren :)
quelle
Ich habe nie darüber nachgedacht, aber ... scheint, dass Sie Recht haben, es gibt kein Problem mit der Vererbungsfunktion für Anmerkungen (zumindest sehe ich das Problem damit nicht).
Über Ihr Beispiel mit der Annotation "Validator" - Sie können dann den Ansatz der "Meta-Annotation" nutzen . Das heißt, Sie wenden eine bestimmte Meta-Annotation auf die gesamte Annotation-Oberfläche an.
quelle
das gleiche Problem habe ich. Nein, das kannst du nicht. Ich habe mich selbst "diszipliniert", um Eigenschaften in Anmerkungen zu schreiben, um einige Standards zu respektieren. Wenn Sie also Anmerkungen erhalten, können Sie außerhalb der Eigenschaften "schnüffeln", welche Art von Anmerkung es ist, nach Eigenschaften, die es hat.
quelle