枚举中的非法前向引用

时间:2015-05-11 13:36:35

标签: 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;
    }
}

我该如何解决?感谢。

2 个答案:

答案 0 :(得分:15)

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

  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,所以它不能用于某些事情,比如注释元素值。

  3. 这也是第三种在实践中有效的方法,但是从Java 9起,不再能保证JLS能够正常工作,因此不应该使用它。

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

    String

    在Java 8中,此{em>的良好行为由8.3.2指定:

      

    请注意,作为常量变量的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; } } 字段在其他static字段之前初始化。 [...]永远不会观察到这些字段具有默认的初始值。

    但是,due to this bug report,措辞已更改为以下in Java 9

      

    请注意,作为常量变量的static字段在其他static字段之前初始化。 [...] 当这些字段以简单名称引用时,永远不会观察到它们具有默认的初始值。

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

答案 1 :(得分:0)

Enum是语法糖,它基本上允许你编写更好的switch语句,并迭代某个类的编译时值集。

在这种情况下,您可以在类Constants这样的类中定义编译时字符串 - 当您遇到这种编译问题时,一般规则是您不应该以这种方式使用枚举并需要其他类< / p>