有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

枚举中的java非法转发引用

我有一个枚举,我试图在构造函数中传递一个最终的静态变量作为参数。问题是枚举中的第一条语句必须是实例本身,但在这种情况下,还并没有定义最终变量。查看代码,您将了解:

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) 个答案

  1. # 1 楼答案

    在我看来,有两种可能的解决方案是合理的

    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_URL是一个constant 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.

    然而,措辞改为如下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.

    上面的代码没有受到bug报告中描述的缺陷的影响,但从Java9开始,它不再保证工作

  2. # 2 楼答案

    Enum是一种语法糖,基本上允许您编写更好的switch语句,以及迭代特定类的编译时值集

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