java - 枚举中的非法前向引用

标签 java enums

我有一个枚举,我正在尝试将最终静态变量作为构造函数中的参数传递。问题是枚举中的第一个语句必须是实例本身,但在这种情况下,最终变量尚未定义。看代码你就明白了:

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;
    }
}

和另一个选项:

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;
    }
}

我该如何解决?谢谢。

最佳答案

有两种可能的解决方案对我来说似乎是合理的。

  1. 使用嵌套类(单独初始化):

    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; }
    }
    

    这是最普遍有用的,因为它没有强加任何重要的限制。

  2. 使用方法:

    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; }
    }
    

    使用方法的一个隐藏缺点是方法调用不是 constant expression ,因此它不能用于某些事情,例如注释元素值。


还有第三种可能的方法在实践中起作用,但从 Java 9 开始,不再保证 JLS 起作用,因此不应使用它。

这使用限定名称 ParseResource.API_URL 而不是简单名称 API_URL 来规避前向引用错误,因为 API_URLconstant variable (即在这种情况下用 String 文字初始化):

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; }
}

在 Java 8 中,此的良好行为由 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.

但是,due to this bug report,写法改成了下面的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.

上述代码不受错误报告中描述的缺陷的影响,但从 Java 9 开始,它不再保证工作。

关于java - 枚举中的非法前向引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30169153/

相关文章:

java - 等效于没有弹出窗口和一个 optional 的 Android 单选按钮?

java - JPA仪器仪表

java - 我应该使用 hibernate 二级缓存吗?

enums - 可以将值映射到名称的 ES6 只读枚举

c# - Enum.GetNames() 导致带有负枚举常量的意外顺序

java - 小物体的像素级碰撞检测失败。 ( java )

java - 如果我使用最新的 JDK 编译 Java 文件,那么旧的 JVM 是否能够运行 .class 文件?

java - 如何在没有实现的情况下将枚举公开给公共(public) API?

java - 我应该如何在 JavaDB 中存储 Java 枚举?

forms - Play 如何为包含枚举的案例类实现隐式写入或格式