我有一个枚举,我试图将最终的静态变量作为参数传递给构造函数。问题是枚举中的第一个语句本身必须是一个实例,但在这种情况下,还没有定义最终变量。查看代码,您将理解:
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;
}
}
我该如何解决?感谢。
答案 0 :(得分:15)
对我来说,有两种可能的解决方案似乎是合理的。
使用嵌套类(单独初始化):
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; }
}
这是最常用的,因为它没有施加任何重要的限制。
使用方法:
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起,
这使用限定名称ParseResource.API_URL
而不是简单名称API_URL
来规避转发引用错误,因为API_URL
是constant 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>