在Java中使用默认值创建Annotation实例

时间:2008-11-05 22:04:06

标签: java annotations instantiation

如何创建以下注释的实例(所有字段都设置为默认值)。

    @Retention( RetentionPolicy.RUNTIME )
    public @interface Settings {
            String a() default "AAA";
            String b() default "BBB";
            String c() default "CCC";
    }

我尝试了new Settings(),但这似乎不起作用......

7 个答案:

答案 0 :(得分:39)

要创建实例,您需要创建一个实现的类:

  • java.lang.Annotation
  • 以及您想要“模拟”的注释

例如:  public class MySettings implements Annotation, Settings

但您需要根据equals界面特别注意hashCodeAnnotation正确实施。 http://download.oracle.com/javase/1.5.0/docs/api/java/lang/annotation/Annotation.html

如果您不想一次又一次地实现这一点,那么请查看javax.enterprise.util.AnnotationLiteral类。 这是CDI(Context Dependency Injection)-API的一部分。 (@see code)

要获取默认值,您可以使用Adrian描述的方式。 Settings.class.getMethod("a").getDefaultValue()

答案 1 :(得分:35)

您无法创建实例,但至少可以获取默认值

Settings.class.getMethod("a").getDefaultValue()
Settings.class.getMethod("b").getDefaultValue()
Settings.class.getMethod("c").getDefaultValue()

然后,可以使用动态代理返回默认值。据我所知,这也是Java本身处理注释的方式。

class Defaults implements InvocationHandler {
  public static <A extends Annotation> A of(Class<A> annotation) {
    return (A) Proxy.newProxyInstance(annotation.getClassLoader(),
        new Class[] {annotation}, new Defaults());
  }
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    return method.getDefaultValue();
  }
}

Settings s = Defaults.of(Settings.class);
System.out.printf("%s\n%s\n%s\n", s.a(), s.b(), s.c());

答案 2 :(得分:24)

我编译并在下面运行,结果令人满意。

class GetSettings {
    public static void main (String[] args){
      @Settings final class c { }
      Settings settings = c.class.getAnnotation(Settings.class);
      System.out.println(settings.aaa());
    }
}

答案 3 :(得分:3)

有同样的问题,我解决了如下。

public static FieldGroup getDefaultFieldGroup() {
    @FieldGroup
    class settring {
    }
    return settring.class.getAnnotation(FieldGroup.class);
}

答案 4 :(得分:1)

如果与方法一起使用:

@Settings
public void myMethod() {
}

现在使用默认值初始化您的注释。

答案 5 :(得分:0)

这适用于Sun / Oracle Java 5,6,7,8 :(但由于涉及sun类,可能会破坏Java 9)。 //编辑刚刚确认这仍然适用于OpenJDK 9b59。

package demo;

import sun.reflect.annotation.AnnotationParser;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class AnnotationProxyExample
{

    public static void main(String[] args)
    {

        System.out.printf("Custom annotation creation: %s%n", 
                createAnnotationInstance(Collections.singletonMap("value", "required"), Example.class));

        System.out.printf("Traditional annotation creation: %s%n", 
                X.class.getAnnotation(Example.class));
    }

    private static <A extends Annotation> A createAnnotationInstance(Map<String, Object> customValues, Class<A> annotationType)
    {

        Map<String, Object> values = new HashMap<>();

        //Extract default values from annotation
        for (Method method : annotationType.getDeclaredMethods())
        {
            values.put(method.getName(), method.getDefaultValue());
        }

        //Populate required values
        values.putAll(customValues);

        return (A) AnnotationParser.annotationForMap(annotationType, values);
    }

    @Example("required")
    static class X
    {
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @interface Example
    {
        String value();
        int foo() default 42;
        boolean bar() default true;
    }
}

输出:

Custom annotation creation: @demo.AnnotationProxyExample$Example(bar=true, foo=42, value=required)
Traditional annotation creation: @demo.AnnotationProxyExample$Example(bar=true, foo=42, value=required)

答案 6 :(得分:0)

如果你有能力改变@Retention( RetentionPolicy.RUNTIME ) public @interface Settings { String DEFAULT_A = "AAA"; String DEFAULT_B = "BBB"; String DEFAULT_C = "CCC"; String a() default DEFAULT_A; String b() default DEFAULT_B; String c() default DEFAULT_C; } 类的主体:

,还有另一种解决方案
Settings.DEFAULT_A

然后你可以简单地引用Excel::create('master',function($excel) use($events){ $excel->sheet('Master List', function($sheet) use($events){ $sheet->fromArray($events); }); })->export('xls'); (是的,更好的名字会有所帮助!)。