Get Rid of "The Value for Annotation Attribute Must Be a Constant Expression" Message

Get rid of The value for annotation attribute must be a constant expression message

The value for an annotation must be a compile time constant, so there is no simple way of doing what you are trying to do.

See also here: How to supply value to an annotation from a Constant java

It is possible to use some compile time tools (ant, maven?) to config it if the value is known before you try to run the program.

Java code won't compile due to attribute must be a constant expression error

The Java rules say that when you have an annotation, and it has a parameter that expects a primitive type (such as an int) or a String, the value must be a constant expression. [This has nothing to do with Spring.] Roughly speaking, a constant expression is one whose value the compiler can figure out at compile time. However, there are rules for what constitutes a constant expression. These rules are in JLS 15.28. Only certain types of operations can be used in a constant expression. A method call, such as Long.toString(), isn't one of those. So using that makes your expression not a constant expression, even though it looks like it should be. (It looks like it to you, because you know what Long.toString does. However, the compiler doesn't keep a catalog of all methods to know which ones are "constant" methods whose values can be figured out at compile time.)

However, the example at the link shows that the + operator can be used, even when one of the arguments is not a string and therefore a toString() method is implicitly called. This suggests that you might be able to make things work like this:

private static final String MAX_LONG_AS_STRING = "" + Long.MAX_VALUE;

I haven't tried it, though.

Java annotation, Attribute value must be constant

private static final String CONSTANT = MyClass.class.getCanonicalName();

These are the modifiers: private static final

This is the data-type/object-type: String

This is the name of your constant/variable/object: CONSTANT

This is the initiator: =

This is the attribute: MyClass.class.getCanonicalName();

Your attribute is not a constant, hence you can't initiate your constant CONSTANT.

Why should the value for an annotation attribute be a constant expression?

An annotation is like a type extension or metadata about the type.

Because java is a statically typed language (meaning that types are known at compile time), it seems reasonable that annotation attribute data (metadata) be known at compile time too - you're defining/declaring data about the annotation (extension).

And as a purely practical point, for annotation processing, which is a compile-time (optional) step, attribute data must be known at compile time - you haven't yet reached a runtime environment, yet you need the attribute data.

Is there any way to avoid this Attribute value must be constant error?

You can use an enum instead of a list of string constants:

@interface InputValidation {
RegularExpressionConstants regularExpression() default
RegularExpressionConstants.FOO_REG_EX;
}

Using an enum allows also moving the name metadata where the pattern is defined

enum RegularExpressionConstants {
FOO_REG_EX("foo", alphanumericWithRange(1, 16)),
BAR_REG_EX("bar", alphanumericWithRange(2,4));

private final String name;
private final String pattern;

private RegularExpression(String name, String pattern) {
this.name = name;
this.pattern = pattern;
}

public String getName() {
return name;
}

public String getPattern() {
return pattern;
}

private static String alphanumericWithRange(int lowerLimit, int upperLimit) {
return "[a-zA-Z0-9]{" + lowerLimit + "," + upperLimit + "}";
}
}

And the annotation can be applied using the enum:

@InputValidation(regularExpression=RegularExpressionConstants.FOO_REG_EX)

Where the annotation is processed, it's enough to just call:

String pattern = field.getAnnotation(InputValidation.class)
.regularExpression()
.getPattern();

Compiler says an annotation's value must be a constant

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.

Attribute value must be constant in retrofit Header

Annotation attribute value must be known at compile-time, only inlined compile-time constants are allowed, like this:

/* static final */ String RAPID_API_KEY = "X-Header-Name: RtaW4YWRtaYWucG..."
/* static final */ String RAPID_API_KEY = "X-Header-Name: " + "RtaW4YWRtaYWucG..."
/* static final */ String RAPID_API_KEY = "X-Header-Name: " + Constants.API_KEY /* API_KEY = "RtaW4YWRtaYWucG..." */

but not

String RAPID_API_KEY = NativeLib.apiKey(); /* Here compiler can't compute NativeLib.apiKey() value */

Alternatively, you can pass header in parameter dynamically using @Header or @HeaderMap

@GET
Call<Post> getVideoByUrl(@HeaderMap Map<String, String> headers,
@Url String url,
@Query("url") String inputUrl);
...
final Map<String, String> headers = new HashMap<>();
headers.put("Key Header Name", NativeLib.apiKey());
headers.put("Host Header Name", NativeLib.apiHost());
...
api.getVideoByUrl(headers, ...);

also you can use an OkHttp interceptor if you want to add the header to all requests.



Related Topics



Leave a reply



Submit