javaannotationssun-codemodeljcodemodel

Java: Generate Annotation with default value using Codemodel


I use the Sun CodeModel code generator for my project. During this I came to the point to generate an annotation class. This class would have an array member which takes an empty array as default values. See the following example:

public class Container {
    public @interface MyAnnotation {
        MyValue[] myValues() default {};
    }
}

I used this code to generate the Annotation

JCodeModel codeModel = new JCodeModel();
JDefinedClass myValueClass = codeModel._class(JMod.PUBLIC, "MyValue", ClassType.CLASS);
JDefinedClass containerClass = codeModel._class(JMod.PUBLIC, "Container", ClassType.CLASS);
JDefinedClass annotationClass = containerClass._annotationTypeDeclaration("MyAnnotation");
annotationClass.method(JMod.NONE, myValueClass.array(), "myValues");

but I have no idea how to generate the default declaration. It only generates the following:

public class Container {
    public @interface MyAnnotation {
        MyValue[] myValues();
    }
}

Solution

  • JMethod has a method declareDefaultValue that allows you to define a default value for an annotation method. The trick after that is to generate the empty array {}. I wasn't able to figure out how to do this using the existing classes, but you can easily define this using a JExpressionImpl:

    JCodeModel codeModel = new JCodeModel();
    JDefinedClass myValueClass = codeModel._class(JMod.PUBLIC, "MyValue", ClassType.CLASS);
    JDefinedClass containerClass = codeModel._class(JMod.PUBLIC, "Container", ClassType.CLASS);
    JDefinedClass annotationClass = containerClass._annotationTypeDeclaration("MyAnnotation");
    JMethod method = annotationClass.method(JMod.NONE, myValueClass.array(), "myValues");
    method.declareDefaultValue(new JExpressionImpl(){
        @Override
        public void generate(JFormatter f) {
            f.p("{}");
        }
    });
    

    This generates the following:

    public @interface MyAnnotation {
        MyValue[] myValues() default {};
    }