Question

I have written my custom annotation and is working fine if i use it as below.

@MyAnnotation("sun")
public void getResult(String id){


}

MyAnnotation.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();

}

above code is working fine. Now instead of hard coding "sun", i would like to keep it in an Enum as below.

public enum WeekDay{

    SUNDAY("sun"), MONDAY("mon");

    private String day;

    WeekDay(String day) {
        this.day= day;
    }


    public String getDay() {
        return this.day;
    }

}

and now with in annotation i do as below.

@MyAnnotation(WeekDay.SUNDAY.getDay())
    public void getResult(String id){


    }

above code gives compilation error in eclipse. It says The value for annotation attribute MyAnnotation.value must be a constant expression. Am i doing anything wrong here?

Thanks!

Was it helpful?

Solution

Change from :

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();

}

To:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    WeekDay value();

}

And use it like this:

@MyAnnotation(WeekDay.SUNDAY)

It will also work if you pass a string literal to your current annotation. Marking your method as final won't work because final on methods only prevents you from overriding it, not returning a constant value. Example:

public final String getString() {
  String[] strings = { "A", "B" };
  return strings[new Random().nextInt(2)]; // returned value is not the same
}

OTHER TIPS

All annotation properties are evaluated and set at compile time. The method getDay() obviously has to wait until the code actually runs to return a value, so you can't use it to set things during compilation!

You can change the type of the Annotation's value to your enum and then simply supply the enum if you want.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
  Weekday value();
}

@MyAnnotation(WeekDay.SUNDAY)
public void getResult(String id){
}

but that might not make any sense if it's meant to accept a broader range of values.

It won't work. You can see an explanation in this answer: https://stackoverflow.com/a/3272859/1912167

However, you can define the annotation to only accept the enum:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    WeekDay value();

}

@MyAnnotation(WeekDay.SUNDAY)
public void getResult(String id){


}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top