10

Java 8 具有称为类型注释 ( JSR 308 ) 的功能。我想将它用于简单的对象到对象映射器框架。我想像这样定义注释@ExpectedType

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExpectedType {
    public Class<?> value();
}

然后在我的代码中使用它,如下所示:

public class SomeServiceImpl() {
    public @ExpectedType(ObjectA_DTO.class) IObjectA doSomething(@ExpectedType(ObjectA_Entity.class) IObjectA obj) {
        return (ObjectA_Entity) obj; // it's correct
    }
}

IObjectA是由类ObjectA_DTO和实现的接口ObjectA_Entity。我想以这种方式使用的服务:

// it's correct
assert someService.doSomething(new ObjectA_DTO()).getClass() == ObjectA_DTO.class;

我想更改 SomeServiceImpl 方法的调用以使用对象映射器。它可以通过使用JSR 269或 AOP 生成的代码来实现。

问题是我写了简单的注释处理器,它根本不处理类型注释。简单注释处理器的源代码如下所示:

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SimpleAnnotationsProcessor extends AbstractProcessor {

    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Messager messager = processingEnv.getMessager();
        try {
            for (TypeElement e : annotations) {
                messager.printMessage(Diagnostic.Kind.NOTE, e.toString());
                for (Element elem : roundEnv.getElementsAnnotatedWith(e)) {
                    messager.printMessage(Diagnostic.Kind.NOTE, elem.toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}

任何想法如何使用或如何通过 SimpleAnnotationsProcessor 访问类型注释?对我来说不需要使用 Pluggable Annotation Processing API,我认为它比 Java 反射具有更好的性能。无论如何,我也不知道如何通过 Java Reflection 访问类型注释。

4

3 回答 3

3

我不确定我是否理解您尝试实现的目标,但这里有一个示例,您可以使用 Java 反射 api 访问您的注释:

package test;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;

public class TypeParameterTest {

    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ExpectedType {
        public Class<?> value();
    }

    public static interface IObjectA {}

    public static class ObjectA_DTO implements IObjectA {}

    public static class ObjectA_Entity implements IObjectA {}

    public static class SomeServiceImpl {
        public @ExpectedType(ObjectA_DTO.class) IObjectA doSomething(@ExpectedType(ObjectA_Entity.class) IObjectA obj) {
            return (ObjectA_Entity) obj;
        }
    }

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        Method m = SomeServiceImpl.class.getMethod("doSomething", IObjectA.class);
        AnnotatedType returnType = m.getAnnotatedReturnType();
        Annotation returnTypeAnnotation = returnType.getAnnotation(ExpectedType.class);
        System.out.println(returnTypeAnnotation);

        AnnotatedType[] parameters = m.getAnnotatedParameterTypes();
        for (AnnotatedType p : parameters) {
            Annotation parameterAnnotation = p.getAnnotation(ExpectedType.class);
            System.out.println(parameterAnnotation);
        }
    }
}

输出如下所示:

@test.TypeParameterTest$ExpectedType(value=class test.TypeParameterTest$ObjectA_DTO)
@test.TypeParameterTest$ExpectedType(value=class test.TypeParameterTest$ObjectA_Entity)

但请注意,并非所有可能的类型注释都可以通过反射 api 访问,但如有必要,您始终可以从字节码中读取它们(请参阅我的答案

于 2015-01-05T14:39:50.913 回答
0

我认为您将在运行时使用注释与各种工具在“编译”时使用注释混为一谈。Processor接口用于工具(编译器、javadoc 生成器),而不是运行时代码。

于 2015-01-05T14:47:23.050 回答
0
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SearchDefinition {

    public String identifier() default "";

}

@SearchDefinition - 可以在任何地方使用

于 2015-01-05T15:16:04.270 回答