2016-04-26 3 views
2

Я использую метод process(), из класса, который наследует от AbstractProcessor, чтобы получить имена элементов, которые используют мою аннотацию.Как сохранить элементы, которые используют мою аннотацию?

Как сохранить список этих имен, чтобы я мог использовать их в своих примерах. main() способ?

@edit У меня есть класс ClassList, который будет хранить имена классов, которые используют аннотацию @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); 
    } 
} 

Здесь у меня есть интерфейс @CustomAnnotation

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

} 

Вот об осуществлении класс, который будет обрабатывать аннотации

@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; 
    } 

} 

Затем я использую аннотацию

@CustomAnnotation 
public class AnnotatedClass { 

} 
@CustomAnnotation 
public class TestClass { 

} 

Теперь, когда у меня есть main() метод, который я хотел бы получить доступ, что классы.

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

Когда я чистый и построить его действительно печатает массив в методе process(), но затем я запустить основную программу список пуст. Как получить доступ к этому списку в основной программе?

+1

Ваш вопрос непонятен. Измените его более подробной информацией о своем фактическом коде и о том, чего вы хотите достичь. – Mxsky

+0

Пожалуйста, постарайтесь сформулировать свои вопросы, добавить больше кода или дать нам больше контекста –

+0

Ok Я отредактировал мое сообщение с некоторым кодом – Humberd

ответ

2

Обработка аннотации происходит во время компиляции. Вы должны сохранить эту информацию до времени выполнения. Единственный способ сделать это - записать его в какое-то постоянное хранилище (например, ресурсы приложения).

  1. Дайте свои аннотации как минимум RetentionPolycy.CLASS, на всякий случай.
  2. В каждом раунде компиляции выполните поиск новых аннотированных элементов и добавьте их имена в набор, как и вы уже сделали (подсказка: сохранение Name экземпляров работает так же хорошо).
  3. Во время последнего раунда компиляции записывайте содержимое этого набора в некоторый файл ресурсов (вы можете найти пример обработчика аннотаций, который генерирует файлы ресурсов, в библиотеке Auto Google).
  4. Прочитайте файл ресурса внутри основного метода вашего приложения
2

Как user1643723 сказал, что процессор должен создать файл ресурсов во время компиляции, что ваше приложение может читать во время выполнения. Вот пример, основанный на вашем коде.

Чтобы создать ресурс, вам необходимо использовать Filer, который предоставляется процессорами processingEnv. Это создаст файл в каталоге базового класса:

Filer filer = processingEnv.getFiler(); 
FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "classnames.txt", (Element[]) null); 
Writer writer = resource.openWriter(); 
for (String className : ClassList.getClassList()) { 
    writer.write(className); 
    writer.write("\n"); 
} 
writer.close(); 

Теперь вы можете загрузить его в своем приложении, как и любой другой ресурс.

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();