我有一个枚举,我试图将最终的静态变量作为参数传递给构造函数.问题是枚举中的第一个语句本身必须是一个实例,但在这种情况下,还没有定义最终变量.查看代码,您将了解:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
和另一种选择:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何解决?谢谢.
Rad*_*def 18
有两种可能的解决方案对我来说似乎是合理的.
使用嵌套类(单独初始化):
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; }
}
Run Code Online (Sandbox Code Playgroud)
这是最普遍有用的,因为它没有施加任何重要的限制.
使用方法:
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; }
}
Run Code Online (Sandbox Code Playgroud)
使用方法的一个隐藏缺点是方法调用不是常量表达式,因此它不能用于某些事情,例如注释元素值.
还有第三种可行的方法在实践中有效,但是从Java 9起,JLS不再能保证工作,所以不应该使用它.
这使用限定名称ParseResource.API_URL而不是简单名称API_URL来规避前向引用错误,因为它API_URL是一个常量变量(即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; }
}
Run Code Online (Sandbox Code Playgroud)
在Java 8中,这种良好的行为是通过指定的8.3.2:
请注意,
static作为常量变量的static字段在其他字段之前初始化.[...]永远不会观察到这些字段具有默认的初始值.
但是,由于此错误报告,Java 9中的措辞已更改为以下内容:
请注意,
static作为常量变量的static字段在其他字段之前初始化.[...] 当这些字段以简单名称引用时,永远不会观察到它们具有默认的初始值.
上面的代码不受bug报告中描述的缺陷的影响,但是从Java 9开始,它不再保证可以工作.
| 归档时间: |
|
| 查看次数: |
3491 次 |
| 最近记录: |