Создайте базовый класс с помощью процессора аннотаций Java

Я хочу использовать процессор аннотаций для создания базового класса аннотируемого класса. Что-то вроде этого:

@ClassGenerator(name="FakeClass") // Generates FakeClass
public class MyClass extends FakeClass {
    ...
}

Это возможно? Или я должен смотреть на другие шаблоны.


person Hounshell    schedule 18.09.2014    source источник
comment
@Fildor Это сделало бы класс, который я должен построить, более элегантным. Мне нужно иметь возможность переопределять вещи в сгенерированном классе. Моей альтернативой было бы разделить его: 1 класс, который определяет, что нужно сгенерировать, второй класс, производный от этого класса, который имеет все переопределения.   -  person Hounshell    schedule 18.09.2014
comment
@afzalex Может ли класс, сгенерированный процессором, заменить существующее определение класса? У меня сложилось впечатление, что нельзя.   -  person Hounshell    schedule 18.09.2014
comment
Извини! Я не понял вашего вопроса. Можете ли вы сделать это более ясным.   -  person afzalex    schedule 18.09.2014
comment
Это лучше? Я пытаюсь создать собственный суперкласс класса. В частности, см. комментарий фрагмента кода.   -  person Hounshell    schedule 18.09.2014
comment
Но зачем вам суперкласс? Вы не могли бы использовать его в другом месте?   -  person Fildor    schedule 18.09.2014
comment
Потому что я хочу переопределить некоторые функции сгенерированного класса вручную, особенно конструкторы, но также иметь некоторые дополнительные методы. Если бы я мог сгенерировать кучу вещей в аннотированном классе, это было бы идеально, но, насколько мне известно, это невозможно без взлома байт-кода, и это не было бы одобрено. Если бы это был С#, я бы сделал его частичным классом и сгенерировал бы другую половину, но в моей среде сборки нет способа сделать это.   -  person Hounshell    schedule 19.09.2014


Ответы (1)


Чтобы ответить на вопрос напрямую... Конечно, вам просто нужно отсканировать ClassGenerator и сгенерировать недостающий класс. Вот базовый рабочий процессор:

@SupportedAnnotationTypes("ClassGenerator")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class BaseClassProcessor extends AbstractProcessor {

    private Elements elements;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        elements = processingEnv.getElementUtils();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(ClassGenerator.class)) {
            TypeMirror mirror = ((TypeElement) element).getSuperclass();

            PackageElement pacakgeElement = elements.getPackageOf(element);
            String packageName = pacakgeElement.getQualifiedName().toString();
            String superClassName = ((DeclaredType) mirror).asElement().getSimpleName().toString();

            try {
                Writer file = processingEnv.getFiler().createSourceFile(packageName + "." + superClassName).openWriter();
                file.write(String.format("package %s; public class %s {}", packageName, superClassName));
                file.flush();
                file.close();
            } catch (IOException ex) {
                Logger.getLogger(BaseClassProcessor.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        return true;
    }
}

Что касается того, является ли этот шаблон целесообразным или лучшим, вам придется проанализировать свои требования и определить, удовлетворяет ли он ваши потребности.

person John Ericksen    schedule 12.05.2015