如何在Java中使用自定义类型注释 [英] How to use custom type annotations in Java

查看:152
本文介绍了如何在Java中使用自定义类型注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 8具有名为Type annotations的功能( JSR 308 ) 。我想将它用于简单的Object to Object映射器框架。我想要像这样定义注释@ExpectedType

Java 8 has feature called Type annotations (JSR 308). I would like to use it for simple Object to Object mapper framework. I would like define annotation @ExpectedType like this

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

然后在我的代码中使用它:

And then use it in my code like this:

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 实现的接口。我想用这种方式服务:

IObjectA is an interface implemented by classes ObjectA_DTO and ObjectA_Entity. The service I would like to use this way:

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

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

I would like change call of SomeServiceImpl methods to use Object mapper. It could be achieved by generated code using JSR 269 or by AOP.

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

The problem is I wrote simple annotations processor and it doesn't handle type annotations at all. The source of simple annotations processor looks like this:

@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访问类型注释。

Any ideas how to use or how to access type annotations by SimpleAnnotationsProcessor? Usage of Pluggable Annotation Processing API is not necessary for me I think it would has better performance than Java reflection. Anyway I don't know how to access type annotation via Java Reflection too.

推荐答案

我不确定我明白你是什么尝试实现,但这里有一个例子,你可以用Java反射api访问你的注释:

I'm not sure I understand what you try to achieve, but here is an example how you can access your annotations with the Java reflection 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,但如果需要,你总是可以从字节码中读取它们(参见我的回答这里)。

Note though, that not all possible type annotations are accessible through the reflection api, but you can always read them from the byte code if necessary (see my answer here).

这篇关于如何在Java中使用自定义类型注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆