Illegal forward reference in enum

Héctor

I have an enum and I'm trying to pass a final static variable as parameter in constructor. Problem is that first statement in enums has to be a instance itself, but in that case, final variable is not defined yet. See the code and you will understand:

public enum ParseResource {

    PUSH(API_URL); //Error: illegal forward reference

    private final static String API_URL = "https://api.parse.com/1";

    private String url;
    private ParseResource(String url) {
        this.url = url;
    }
}

and the other option:

public enum ParseResource {

    //Illegal in enums, first statement has to be an instance
    private final static String API_URL = "https://api.parse.com/1";

    PUSH(API_URL);

    private ParseResource(String url) {
        this.url = url;
    }
}

How can I solve it? Thanks.

Radiodef

There are two possible solutions which seem reasonable to me.

  1. 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.

  2. 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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

illegal forward reference netbeans swing

From Dev

Problem with illegal forward reference in Java

From Dev

Why illegal forward reference error not shown while using static variable with class name

From Dev

Illegal dynamic reference

From Dev

Lazy forward reference in Haskell

From Dev

Perl regex forward reference

From Dev

Forward Declaring enum class not working

From Dev

Pass enum with enum class by reference

From Dev

Reference to parameters within an enum

From Dev

Store enum class reference

From Dev

Reference a nested enum in a dictionary?

From Dev

Set a reference to an Enum

From Dev

Funny issue with incorrect forward reference

From Dev

Appropriate way to forward rvalue reference

From Dev

forward const reference through function

From Dev

Working of std::forward and reference collapsing

From Dev

forward reference with a lookbehind C#?

From Dev

Funny issue with incorrect forward reference

From Dev

forward reference with a lookbehind C#?

From Dev

Wrong forward reference with Null initialisation

From Dev

Why It is illegal to copy an object if a member of the class is a reference?

From Dev

illegal reference to static field from initializer

From Dev

Forward declaring enum in C++ defined in C

From Dev

Is in-class enum forward declaration possible?

From Dev

"chmod --reference=<reference file> <file>" returns "chmod: illegal option -- -" on macOS

From Dev

Creating object from enum reference

From Dev

What is the syntax to match on a reference to an enum?

From Dev

Creating object from enum reference

From Dev

Swift enum's unwrapping by reference