为啥直到类回调被击中后才构造 java 枚举?
Posted
技术标签:
【中文标题】为啥直到类回调被击中后才构造 java 枚举?【英文标题】:Why is a java enum not constructing till after a class callback is hit?为什么直到类回调被击中后才构造 java 枚举? 【发布时间】:2012-06-19 17:11:24 【问题描述】:我有一个 android 类,它有一个来自异步 HTTP 进程的回调,以及一个带有多个状态代码的枚举:
public abstract class HttpPackage
public enum StatusCode
SUCCESS(0),
NOT_FOUND(100),
USERNAME_NOT_FOUND(101),
AUTH_FAILED(110),
SAVE_ERROR(111)
//etc.
private final int mCode;
StatusCode(int i)
mCode = i;
sByCode.put(i, this);
private static final HashMap<Integer, StatusCode> sByCode = new HashMap<Integer, StatusCode>();
//...
我发现 HttpPackage 类中的回调在 enum
构造之前被命中,这意味着当我尝试从静态代码映射中提取状态代码时,它返回 null,我的代码认为所有提要失败(当它们没有失败时)。为什么这个enum
会在回调被命中后构造?
【问题讨论】:
当你已经有一个状态码枚举时,为什么还要麻烦有一个状态码的外部映射?为什么不将它保存在枚举中? 它不会编译。我刚刚发现删除static
修饰符会有所帮助,但这让我没有静态方式来访问地图。
你通过枚举访问它。
没有静态方式。见下文。
【参考方案1】:
类在 Java 中是延迟加载的。如果您在加载 StatusCode 类之前访问地图,那么它当然是空的。
地图应该在枚举本身中。这样,如果您正在访问地图,则可以保证枚举类已加载,并且地图不为空。地图也应该对外部代码隐藏。你应该在枚举中提供一个静态的StatusCode getByCode(int code)
方法。
编辑:示例代码:
public enum StatusCode
SUCCESS(0),
NOT_FOUND(100),
USERNAME_NOT_FOUND(101),
AUTH_FAILED(110),
SAVE_ERROR(111);
private final int code;
private static final Map<Integer, StatusCode> map = new HashMap<Integer, StatusCode>();
static
for (StatusCode sc : values())
map.put(sc.getCode(), sc);
StatusCode(int i)
this.code = i;
public static StatusCode getByCode(int code)
return map.get(code);
public int getCode()
return code;
public static void main(String[] args)
System.out.println(StatusCode.getByCode(111));
或者您也可以在构造函数中使用 getMap()
静态方法,如果地图为空,则延迟初始化地图。
【讨论】:
另外,请记住,泛型类型参数在编译时会被删除,因此 sByCode 不会在运行时引用 StatusCode 类,这会导致在访问地图时加载该类。跨度> 如果我将sByCode
设为静态,它不会在enum
构造函数中初始化,如果我不将其设为静态,getByCode
方法将看不到它。有什么想法吗?
我已经使用简单的“遍历values()
并检查是否相等,返回匹配”方法解决了这个问题,但不能使用HashMap
似乎很遗憾。
@AndrewWyld 我见过的典型解决方法是使 sByCode 成为枚举类的静态成员,然后在静态初始化程序块中用枚举值填充它。
啊,静态初始化器。没想到。谢谢!以上是关于为啥直到类回调被击中后才构造 java 枚举?的主要内容,如果未能解决你的问题,请参考以下文章
java中,当实例化子类时会递归调用父类中的构造方法。这个说法对么?为啥