Я не очень знаком со сканерами пути к классам, которые предлагают другие.Они кажутся надежным - если не идеальным - решением.
Если у вас есть контроль над источником, вы можете использовать обработку аннотаций.
Создать процессор аннотаций, который создаст класс - MapClass
со статическим элементом Map<String,Foo>
.Каждый раз, когда обработчик аннотаций встречает аннотацию @Name, он добавляет это к исходному коду MapClass
.Когда он завершит обработку аннотаций, он будет иметь такой же эффект, как если бы вы жестко закодировали карту.
Обработка аннотаций происходит во время компиляции.Если некоторые классы в вашем проекте не скомпилированы вами.Например, если кто-то еще скомпилирует некоторые классы и даст вам банку, тогда это не будет работать так же легко.Но если все классы скомпилированы вами, это не должно быть проблемой.
Чтобы создать процессор аннотаций, добавьте AbstractProcessor
.Вы можете аннотировать свой класс с помощью аннотации @ SupportedAnnotationTypes ( "Name" )
(убедитесь, что name - это полное имя вашей аннотации.
Переопределите метод process
. process
имеет два параметра: annotations
и roundEnv
. annotations
- это просто набор аннотаций, которые поддерживает данный конкретный процессор - в вашем случае это должно быть (Name). roundEnv
- полезный служебный класс.
Выполните итерацию по одной аннотации в annotations
. Используйте от roundEnv
до getElementsAnnotatedWith
. Это должно дать вам набор всех элементов, которые содержат аннотацию @Name
.
AbstractProcessor
имеет еще один служебный элемент - processingEnv
. Используйте его getFiler
метод для createSourceFile
.
Затем вы должны немного изменить свою компиляцию. Вы должны скомпилировать ваш процессор отдельно и до других классов. После того, как процессор скомпилирован и вы компилируете другие классы, вы должны сообщить компилятору о вашем процессоре. Если вы используетеКомандная строка вы бы добавили -processorpath /path/to/processor/class[es]
и-processor qualified.name.of.processor
.
Преимущества этого подхода перед сканером путей к классам в том, что все происходит во время компиляции.Например, если вы случайно добавили аннотацию @Name
к элементу Bar
, процессор может выдать ошибку времени компиляции (если вы хотите, чтобы процессор мог ее игнорировать).Затем вы можете исправить это, прежде чем продукт будет отправлен.В сканере путей к классам любая выброшенная ошибка является ошибкой во время выполнения, которую увидит пользователь.
Недостатком этого подхода также является то, что все происходит во время компиляции.Это усложняет динамическое добавление классов в проект.