2009-07-16 4 views
9

Mir ist klar, dass dies eine Frage ist, die gestellt und beantwortet wurde, aber bitte ertragen Sie mit mir.Können Anmerkungen für die Code-Injektion verwendet werden?

Ich möchte wissen, ob es möglich ist, Anmerkungen zu verwenden, um Code in die Klassenkompilierungszeit zu injizieren. Das klassische Beispiel besteht darin, einen Getter und Setter für die Mitglieder Ihres Objekts zu generieren. Dies ist nicht genau das, wofür ich es brauche, aber es dient dazu, die Grundidee zu veranschaulichen.

nun im Internet die grundlegende Antwort, die ich nicht bekommen, aber dieser Kerl hat es geschafft:

link text

Wer weiß, wie er das tut, was er tut (und wenn er tatsächlich tut, was er sagt, er tut)?

Die Hauptsache ist, dass er keinen Annotationsprozessor verwendet, um eine neue Java-Datei zu kompilieren. Diese Technik ist mir bewusst und wird nicht für unseren Zweck funktionieren.

Dank

+0

Ich denke, er könnte das möglicherweise tun http://jcp.org/en/jsr/detail?id=269? – Chii

Antwort

5

Es wird nicht unterstützt Code während der Kompilierung zu ändern, aber es scheint, durch Verwendung von nicht unterstützten javac-interner APIs möglich zu sein, ist here ein Beitrag die hanbuy-panno Lösung mit auch einem Link zur code Referenzierung ...

+0

Vielen Dank. Dieser zweite Link ist genau das, wonach ich gesucht habe. Jetzt kann ich sehen, wie er es macht und entscheiden, ob es eine gute/schlechte Idee ist, es so zu machen. –

+0

Diese Links funktionieren nicht mehr. Gibt es einen Spiegel? –

1

Etwas muss die Anmerkungen verarbeiten, also entweder geschieht es bei der Kompilierung mit einer Anmerkung Prozessor oder zur Laufzeit mit Reflexion (ja, ich weiß, gibt es noch exotischere Möglichkeiten, es zur Laufzeit zu tun).

Er verwendet definitiv einen Annotationsprozessor, es ist nur implizit. Der Befehl javac durchsucht den Klassenpfad nach Annotationsprozessoren, wenn er nicht explizit festgelegt wurde.

Da er diesen Befehl verwendet, um zu kompilieren:

javac -cp ~/development/panno/build/hanhuy-panno.jar *.java

Wir sehen, dass er den Klassenpfad die hanhuy-panno.jar so modifiziert wird, die die Anmerkung Prozessor enthalten wird.

Warum mailen Sie nicht einfach den Kerl und fragen, ob er Ihnen den Code geben wird?

+0

Ja, ich merke, dass er es mit einem Annotationsprozessor macht, die Frage ist mehr, was er darin macht. Ich habe ihn geschickt, aber ich habe noch keine Antwort erhalten. Danke –

3

Ich suchte letztes Jahr nach something similar. Es gibt keine standardmäßige Möglichkeit, Klassen mithilfe von Annotationsprozessoren oder dem Compiler zu ändern, und die Annotation-API-Dokumentation empfiehlt, Dekoratoren zu erstellen.

Wenn Sie bereit sind, mit den Hacks leben, sehen Sie sich Adrian Kuhn Verwendung der privaten API, wo er adds Roman numeral literals to Java. Dieser Ansatz ist auf den Sun Javac-Compiler beschränkt und Sie müssten etwas anderes implementieren, wenn Sie einen anderen (wie den Eclipse-Compiler) verwenden würden.


Edit: alle Interessierten in diesem Bereich sollte Project Lombok überprüfen.

+0

Ah, ich verstehe, was Sie damit meinen, sich auf einen bestimmten Compiler zu beschränken. Das könnte ein Problem sein. Danke für die Antwort. –

2

Sie können dies tun, aber Sie dürfen die Klasse mit den Anmerkungen nicht ändern. (Der Trick, zu dem Sie eine Verknüpfung herstellen, verwendet die Kompilierbaum-API, um den erzeugten Bytecode zu ändern ...) Dies wird nicht unterstützt und wird wahrscheinlich in späteren Java-SDKs verhindert.

Der richtige Weg, um es zu tun, ist eine Oberklasse, Unterklasse oder Wrapper-Klasse zu generieren.

Ich habe eine Reihe von Anmerkungen geschrieben, die Getter/Setter und andere lustige Sachen erzeugen. Ich erzeuge eine Oberklasse.

Siehe http://code.google.com/p/javadude/wiki/Annotations

Sie Dinge tun können wie

package sample; 

import com.javadude.annotation.Bean; 
import com.javadude.annotation.Property; 
import com.javadude.annotation.PropertyKind; 

@Bean(properties={ 
    @Property(name="name"), 
    @Property(name="phone", bound=true), 
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST) 
}) 
public class Person extends PersonGen { 
} 

und es wird PersonGen mit den Feldern/Getter/Setter und gebundene Eigenschaft Unterstützung für Sie generieren.

+0

Danke für die Antwort, aber wie ich in meiner ursprünglichen Frage festgestellt habe, ist die Generierung anderer Java-Dateien in unserem Fall keine ideale Lösung. Ich stimme zwar zu, dass die Verwendung der Kompilierbaum-API auch nicht ideal ist. –

+0

Irgendein bestimmter Grundcode gen funktioniert nicht für Sie? Denken Sie daran, dass der Codebaum nicht nur für diesen Zweck nicht ideal ist, sondern in den APT-Dokumenten ausdrücklich angegeben ist, dass er illegal ist. –