2016-04-26 19 views
2

Ich verwende die Methode process() aus der Klasse, die von AbstractProcessor erbt, um die Namen von Elementen zu erhalten, die meine Annotation verwenden.Wie kann ich Elemente speichern, die meine Annotation verwenden?

So speichern Sie eine Liste dieser Namen, damit ich sie in meinem verwenden kann. main() Methode?

@edit Ich habe eine Klasse ClassList, die die Namen der Klassen gespeichert werden, die die Anmerkung verwenden @CustomAnnotation

public class ClassList { 
    private static final List<String> classList= new LinkedList<>(); 

    public static List<String> getClassList() { 
     return classList; 
    } 

    public static void addList(String name) { 
     classList.add(name); 
    } 
} 

Hier habe ich die Schnittstelle @CustomAnnotation

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface CustomAnnotation{ 

} 

Hier ist die Umsetzung der Klasse, die die Anmerkungen verarbeiten wird

@SupportedAnnotationTypes("com.example.CustomAnnotation") 
@SupportedSourceVersion(SourceVersion.RELEASE_8) 
public class CompileTimeAnnotationProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, 
      RoundEnvironment roundEnv) { 
     Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(CustomAnnotation.class); 
     for (Element e : elements) { 
      //adds each name to the list 
      ClassList.addList(e.getSimpleName().toString()); 
     } 
     //prints the array 
     System.out.println(Arrays.toString(ClassList.getClassList().toArray(new String[ClassList.getClassList().size()]))); 
     return true; 
    } 

} 

Dann benutze ich die Anmerkung

@CustomAnnotation 
public class AnnotatedClass { 

} 
@CustomAnnotation 
public class TestClass { 

} 

Nun, wenn ich die main() Methode hätte ich, dass Klassen zugreifen möchten.

public static void main(String[] args) { 
    System.out.println(ClassList.getClassList().size()); 
} 

Wenn ich sauber und baut es in der Tat druckt das Array in dem Verfahren process(), aber dann laufen i das Hauptprogramm die Liste leer ist. Wie erreiche ich diese Liste im Hauptprogramm?

+1

Ihre Frage ist überhaupt nicht klar.Bearbeiten Sie es mit mehr Details Ihres tatsächlichen Codes und was Sie erreichen möchten. – Mxsky

+0

Bitte versuchen Sie, Ihre Fragen zu bearbeiten, fügen Sie mehr Code hinzu oder geben Sie uns mehr Kontext –

+0

Ok Ich habe meinen Beitrag mit etwas Code bearbeitet – Humberd

Antwort

2

Die Annotationsverarbeitung findet zur Kompilierungszeit statt. Sie müssen diese Informationen bis zur Laufzeit speichern. Die einzige Möglichkeit, dies zu tun, ist das Schreiben in einen permanenten Speicher (z. B. Anwendungsressourcen).

  1. Geben Sie Ihre Anmerkungen mindestens RetentionPolycy.CLASS, nur für den Fall.
  2. Suchen Sie in jeder Kompilierungsrunde nach neuen annotierten Elementen und fügen Sie deren Namen zu einem Set hinzu, so wie Sie es bereits tun (Hinweis: das Speichern von Name Instanzen funktioniert genauso gut).
  3. Während der letzten Kompilierungsrunde schreiben Sie den Inhalt dieses Sets in eine Ressourcendatei (ein Beispiel für den Annotationsprozessor, der Ressourcendateien generiert, finden Sie in Googles Auto Bibliothek).
  4. Lesen Sie die Ressource-Datei innerhalb des Haupt Methode Ihrer Anwendung
2

Wie user1643723 sagte der Prozessor benötigt eine Ressource-Datei bei der Kompilierung zu erstellen, die Ihre Anwendung dann zur Laufzeit lesen kann. Hier ist ein Beispiel basierend auf Ihrem Code.

Um eine Ressource zu erstellen, müssen Sie die Filer verwenden, die von den Prozessoren processingEnv bereitgestellt wird. Dadurch wird eine Datei im Klassenbasisverzeichnis erstellt:

Jetzt können Sie es wie jede andere Ressource in Ihre Anwendung laden.

InputStream is = getClass().getResourceAsStream("/classnames.txt"); 
BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
String line = null; 
while ((line = reader.readLine()) != null) { 
    System.out.println(line); 
} 
reader.close();