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 typeT
is commensurate with an
element valueV
if and only if one of the following is true:
- If
T
is a primitive type orString
, thenV
is a constant expression (§15.28).- If
T
is anenum
type (§8.9), then V is anenum
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
How to Change the Dock Icon of a Java Program
Changing Swing Jtable Cell Colors
Why Do We Assign a Parent Reference to the Child Object in Java
What Does It Mean: the Serializable Class Does Not Declare a Static Final Serialversionuid Field
"Int Cannot Be Dereferenced" in Java
Jformattedtextfield:Input Time Duration Value
Should Private Helper Methods Be Static If They Can Be Static
Generic Type Parameter Naming Convention for Java (With Multiple Chars)
Java 8 Stream's .Min() and .Max(): Why Does This Compile
Java: How to Access Methods from Another Class
Java Enum and Additional Class Files
Get Rid of "The Value for Annotation Attribute Must Be a Constant Expression" Message
How to Compare Character Ignoring Case in Primitive Types
How to Have a Textfield Inside a Label
How to Call Getclass() from a Static Method in Java