简体   繁体   中英

Using Java 8 is there a way to validate/assert that a constant is a compile-time constant?

I'd like to have a JUnit test that verifies a specific constant is a Compile-Time Constant. How would I go about doing that?

I found a solution for Scala, but I'd like on for plain Java.
Is there a way to test at compile-time that a constant is a compile-time constant?

Root Cause:

The value for annotation attribute ApiModelProperty.allowableValues must be a constant expression

What I'd like in a Unit Test:
  validateCompileTimeConstant(SomeClass.CONSTANT_VALUE, "Message Here!!"); 
Usage
  @ApiModelProperty(name = "name", required = true, value = "Name", allowableValues=SomeClass.API_ALLOWABLE_VALUES, notes=SomeClass.API_NOTES) private String name; 
SomeClass
 public enum SomeClass { BOB(4, "Bob"),// TED(9, "Ted"),// NED(13, "Ned"); public static final String API_ALLOWABLE_VALUES = "4,9,13,16,21,26,27,170"; public static final String API_NOTES = "4 - Bob\\n" + "9 - Ted\\n" + "13 - Ned"; public int code; public String desc; private ContentCategoryCode(int code, String desc) { this.code = code; this.desc = desc; } public static final String apiAllowableValues() { StringBuilder b = new StringBuilder(); for (ContentCategoryCode catCode : values()) { b.append(catCode.code); b.append(','); } b.setLength(b.length()-1); return b.toString(); } public static final String apiNotes() { StringBuilder b = new StringBuilder(); for (ContentCategoryCode catCode : values()) { b.append(catCode.code).append(" - ").append(catCode.desc); b.append('\\n'); } b.setLength(b.length()-1); return b.toString(); } } 

The Error Prone project has a @CompileTimeConstant annotation which can be used to enforce exactly this.

It's not a test that you run with JUnit, but a compiler plug-in that enforces this (and other bug patterns) at compile time.

Here is the documentation: https://errorprone.info/bugpattern/CompileTimeConstant

I ended up creating my own annotation, since it required less setup than using Error Prone.

Annotation Class:

@Target(ElementType.METHOD)
public @interface TestCompileTimeConstant {
    public String key() default "";
}

JUnit Test:

public class SomeClassTest {

    @Test
    public void test() {
        assertEquals(SomeClass.API_ALLOWABLE_VALUES, SomeClass.apiAllowableValues());
        assertEquals(SomeClass.API_NOTES, SomeClass.apiNotes());
    }

    @Test
    @TestCompileTimeConstant(key=SomeClass.API_ALLOWABLE_VALUES)
    public void testIsCompileTimeConstant1() {
        //Pass - If this doesn't compile, you need to make sure API_ALLOWABLE_VALUES doesn't call any methods.
    }

    @Test
    @TestCompileTimeConstant(key=SomeClass.API_NOTES)
    public void testIsCompileTimeConstant2() {
        //Pass - If this doesn't compile, you need to make sure API_NOTES doesn't call any methods. 
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM