I have a class that have a number of constants:
public class SecurityConstants {
private static final String HAS_ROLE_TEMPLATE = "hasRole('%s')";
public static final String ROLE_USER_INTERNAL = "ROLE_USER_INTERNAL";
public static final String HAS_ROLE_USER_INTERNAL = String.format(HAS_ROLE_TEMPLATE, ROLE_USER_INTERNAL);
}
If I then try to use HAS_ROLE_USER_INTERNAL
as @PreAuthorize
annotation attribute value like this @PreAuthorize(SecurityConstants.HAS_ROLE_USER_INTERNAL)
compiler fails with:
The value for annotation attribute PreAuthorize.value must be a constant expression
However if I change HAS_ROLE_USER_INTERNAL
to be a simple String
it works just fine:
public static final String HAS_ROLE_USER_INTERNAL = "hasRole('ROLE_USER_INTERNAL')";
What's the problem with using String.format()
? Field is static
and final
, what can possibly go wrong?
In java, String format() method returns a formatted string using the given locale, specified format string, and arguments. We can concatenate the strings using this method and at the same time, we can format the output concatenated string.
When we create a custom annotation, we declare elements as methods and later set values as if they were attributes. For example, here we have declared a custom annotation ComponentType with elements name() and description() that look like methods.
The value of String.format()
isn't known at compile time, whereas a String
literal is.
Since the annotations are metadata on the compiled class, their values must be known by the time the compiler generates the final .class file. Since String.format()
's value will only be known once the code is actually run, the compiler won't let you use it as part of an annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With