如何在Java中使用自定义类型注释

Java 8具有名为Type annotations( JSR 308 )的function。 我想将它用于简单的Object to Object映射器框架。 我想像这样定义注释@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_DTOObjectA_Entity类实现的接口。 我想用这种方式服务:

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

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

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

 @SupportedAnnotationTypes("*") @SupportedSourceVersion(SourceVersion.RELEASE_8) public class SimpleAnnotationsProcessor extends AbstractProcessor { public boolean process(Set 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对我来说不是必需的我认为它会比Javareflection具有更好的性能。 无论如何我也不知道如何通过Java Reflection访问类型注释。

我不确定我理解你想要实现的目标,但这里有一个例子,你可以用Javareflectionapi访问你的注释:

 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) 

但请注意,并非所有可能的类型注释都可以通过reflectionapi访问,但是如果需要,您可以始终从字节代码中读取它们(请参阅我的答案)。

我认为你在运行时混淆了注释的使用,而不是在各种工具的“编译”时间使用注释。 Processor接口用于工具(编译器,javadoc生成器),而不是在运行时代码中。

 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface SearchDefinition { public String identifier() default ""; } 

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