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

56,081

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.

Share:
56,081
Kassandra Hinojosa Rodriguez
Author by

Kassandra Hinojosa Rodriguez

Student of Electronics Engineering in Puebla, Mexico.

Updated on July 09, 2022

Comments

  • Kassandra Hinojosa Rodriguez
    Kassandra Hinojosa Rodriguez almost 2 years

    I can't figure out why the following won't compile. The error the IDE gives me is "The value for annotation attribute RequestParam.defaultValue must be a constant expression".

    My project involves Spring and Maven, and it goes the following:

    private static final String MAX_LONG_AS_STRING = Long.toString(Long.MAX_VALUE);
    
    @RequestMapping(method=RequestMethod.GET)
    public List<Spittle> spittles(
            @RequestParam(value="max",
                        defaultValue=MAX_LONG_AS_STRING) long max,
            @RequestParam(value="count", defaultValue="20") int count) {
        return spittleRepository.findSpittles(max, count);
    }
    

    I'm thinking the error comes from the conversion of Long to String, but I do not know how to fix it. I will appreciate any help, I am new to annotations and Spring.

  • Kassandra Hinojosa Rodriguez
    Kassandra Hinojosa Rodriguez over 7 years
    Ohh! Thank you very much for your help, the option you gave me does work! And the link and explanation you gave really helped understand more about constant expressions. I wasn't aware about the compile time difference until I investigated more, but didn't know it had something to do with the method usage as well. Thank you very much for brief but great explanation!
  • junvar
    junvar over 6 years
    toString() is a method call at runtime. "" + 5 creates a constant string (as they are immutable) at compile time - i may be wrong
  • ajb
    ajb over 6 years
    @junvar Nothing prevents a compiler from creating a constant string for Long.toString(Long.MAX_VALUE). There are multiple Java compilers, and each one could decide whether to optimize this to a constant string or not. However, Java's rules about what is legal or not are the same regardless of compiler. The legality rules don't depend on optional optimizations that a compiler may or may not make.
  • vipin
    vipin over 4 years
    why static final Integer WINDOW_SIZE = 300; is also giving me not a constant expression, there is no method call here ?
  • ajb
    ajb over 4 years
    @vipin I think we'd need a Minimal Reproducible example, and it should be a new question
  • Sumit Kandoi
    Sumit Kandoi over 4 years
    can I make this private static final String INSTANCE_ID = "" + UUID.randomUUID().toString(); as a constant expression?
  • ajb
    ajb over 4 years
    @SumitKandoi No. (You can declare the INSTANCE_ID, but you can't use it in an annotation.) Your expression contains two method calls, and constant expressions can't have any. Furthermore, randomUUID() isn't something that can be computed at compile time--it should return a different value every time it's called, which means computing it at compile time is out of the question.
  • Nicholas
    Nicholas over 3 years
    @vipin Integer is not a primitive type. Use int.