How to create an instance of an annotation

前端 未结 8 1190
无人及你
无人及你 2021-01-30 12:47

I am trying to do some Java annotation magic. I must say I am still catching up on annotation tricks and that certain things are still not quite clear to me.

So... I hav

相关标签:
8条回答
  • 2021-01-30 13:20

    Well, it's apparently nothing all that complicated. Really!

    As pointed out by a colleague, you can simply create an anonymous instance of the annotation (like any interface) like this:

    MyAnnotation:

    public @interface MyAnnotation
    {
    
        String foo();
    
    }
    

    Invoking code:

    class MyApp
    {
        MyAnnotation getInstanceOfAnnotation(final String foo)
        {
            MyAnnotation annotation = new MyAnnotation()
            {
                @Override
                public String foo()
                {
                    return foo;
                }
    
                @Override
                public Class<? extends Annotation> annotationType()
                {
                    return MyAnnotation.class;
                }
            };
    
            return annotation;
        }
    }
    

    Credits to Martin Grigorov.

    0 讨论(0)
  • 2021-01-30 13:21

    Rather crude way using the proxy approach with the help of Apache Commons AnnotationUtils

    public static <A extends Annotation> A mockAnnotation(Class<A> annotationClass, Map<String, Object> properties) {
        return (A) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class<?>[] { annotationClass }, (proxy, method, args) -> {
            Annotation annotation = (Annotation) proxy;
            String methodName = method.getName();
    
            switch (methodName) {
                case "toString":
                    return AnnotationUtils.toString(annotation);
                case "hashCode":
                    return AnnotationUtils.hashCode(annotation);
                case "equals":
                    return AnnotationUtils.equals(annotation, (Annotation) args[0]);
                case "annotationType":
                    return annotationClass;
                default:
                    if (!properties.containsKey(methodName)) {
                        throw new NoSuchMethodException(String.format("Missing value for mocked annotation property '%s'. Pass the correct value in the 'properties' parameter", methodName));
                    }
                    return properties.get(methodName);
            }
        });
    }
    

    The types of passed properties are not checked with the actual type declared on the annotation interface and any missing values are discovered only during runtime.

    Pretty similar in function to the code mentioned in kaqqao's answer (and probably Gunnar's Answer as well), without the downsides of using internal Java API as in Tobias Liefke's answer.

    0 讨论(0)
提交回复
热议问题