kuporific
kuporific

Reputation: 10322

Compiler says an annotation's "value must be a constant"

I have a Spring1 @Controller annotated class with @RequestMapping annotated methods. I want to reference values for the @RequestMapping parameters, value and method, from another class, rather than hard coding them into the annotation.

Example

Instead of

@Controller
public class MyController {
    @RequestMapping(value="my/path", method=RequestMethod.GET)
    public String handlePath() {
        // etc...
    }
}

I want two files,

@Controller
public class MyController {
    @RequestMapping(value=Constants.PATH, method=Constants.PATH_METHOD)
    public String handlePath() {
        // etc...
    }
}

and

public class Constants {
    public static final String PATH = "my/path";
    public static final RequestMethod PATH_METHOD = RequestMethod.GET;
}

Unfortunately, this fails with the following compile-time error:

error: an enum annotation value must be an enum constant
        @RequestMapping(value=Constants.PATH, method=Constants.PATH_METHOD)
                                                              ^

Question

Why does this work in the case of String but does not work for enums?


Notes

  1. This question is not Spring specific, this is just an (hopefully) accessible example of this issue.
  2. I happen to be using Java 8

Upvotes: 3

Views: 9901

Answers (1)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279990

We need to look at what the Java Language Specification says is an acceptable value for an annotation method.

It is a compile-time error if the element type is not commensurate with the element value. An element type T is commensurate with an element value V if and only if one of the following is true:

  • If T is a primitive type or String, then V is a constant expression (§15.28).
  • If T is an enum type (§8.9), then V is an enum constant (§8.9.1).

PATH_METHOD is not an enum constant. RequestMethod.GET is an enum constant. For String, this

public static final String PATH = "my/path";

is a constant variable, which is a constant expression and therefore can be used.

It shouldn't work even if the constant was declared in the same file. Please review.

Upvotes: 4

Related Questions