There are two possible solutions which seem reasonable to me.
Using a nested class (which is initialized separately):
public enum ParseResource {
PUSH(Constants.API_URL);
private static class Constants {
private static final String API_URL = "https://api.parse.com/1";
}
private String url;
private ParseResource(String url) { this.url = url; }
}
That's the most generally useful, because it doesn't impose any important restrictions.
Using a method:
public enum ParseResource {
PUSH(getApiUrl());
private static String getApiUrl() { return "https://api.parse.com/1"; }
private String url;
private ParseResource(String url) { this.url = url; }
}
One hidden downside to using a method is that a method invocation isn't a constant expression, so it can't be used for some things, like annotation element values.
There's also a 3rd possible way which works in practice, but as of Java 9 is no longer guaranteed by the JLS to work, so it shouldn't be used.
This used the qualified name ParseResource.API_URL
instead of the simple name API_URL
to circumvent the forward reference error, because API_URL
is a constant variable (i.e. initialized with a String
literal in this case):
public enum ParseResource {
PUSH(ParseResource.API_URL);
private static final String API_URL = "https://api.parse.com/1";
private String url;
private ParseResource(String url) { this.url = url; }
}
In Java 8, the good behavior of this was specified by 8.3.2:
Note that static
fields that are constant variables are initialized before other static
fields. [...] Such fields will never be observed to have their default initial values.
However, due to this bug report, the wording was changed to the following in Java 9:
Note that static
fields that are constant variables are initialized before other static
fields. [...] When such fields are referenced by simple name, they will never be observed to have their default initial values.
The above code was not affected by the defect described in the bug report, but as of Java 9 it's no longer guaranteed to work.