Domanda

Is there any way to define static final variables (effectively constants) in a Java enum declaration?

What I want is to define in one place the string literal value for the BAR(1...n) values:

@RequiredArgsConstructor
public enum MyEnum {
    BAR1(BAR_VALUE),
    FOO("Foo"),
    BAR2(BAR_VALUE),
    ...,
    BARn(BAR_VALUE);

    private static final String BAR_VALUE = "Bar";

    @Getter
    private final String value;
}

I got the following error message for the code above: Cannot reference a field before it is defined.

È stato utile?

Soluzione

As IntelliJ IDEA suggest when extracting constant - make static nested class. This approach works:

@RequiredArgsConstructor
public enum MyEnum {
    BAR1(Constants.BAR_VALUE),
    FOO("Foo"),
    BAR2(Constants.BAR_VALUE),
    ...,
    BARn(Constants.BAR_VALUE);



    @Getter
    private final String value;

    private static class Constants {
        public static final String BAR_VALUE = "BAR";
    }
}

Altri suggerimenti

public enum MyEnum {
    BAR1(MyEnum.BAR_VALUE);

    public static final String BAR_VALUE = "Bar";

works fine

class Scratch {
    public static void main(String[] args) {
        System.out.println(MyEnum.BAR3); // 10:BAR3
    }
}
enum MyEnum {
//  BAR1(       foo),   // error: illegal forward reference
//  BAR2(MyEnum.foo2),  // error: illegal forward reference
    BAR3(MyEnum.foo);   // no error

    int x;

    public static final int foo =10;
    public static       int foo2=20;
    MyEnum(int i) {x = i;}

    @Override public String toString() { return x+":"+super.toString(); }
}

This can be done without an inner class for the constant. And field initialization works as expected (in case you don't know, it is possible to read static fields before they are initialized, you will read the default 0 or null, but it does not happen here).

Maybe you should considering breaking this enum into two fields: an enum and an int:

@RequiredArgsConstructor
public enum MyEnum {
    BAR("Bar"),
    FOO("Foo")

    @Getter
    private final String value;
}

And then use:

private MyEnum type;
private int value;

(You can put that into a class or not, whether it makes sense to you)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top