大家都知道Android推荐用常量代替枚举enum,这个问题先不讨论。
先假设如果一定要用enum
假设java情况下,enum初始化时用到常量或者静态方法的时候,是很容易的,可以看到下面代码该枚举用到静态方法arraySetof()
public enum MimeType {
JPEG("image/jpeg", arraySetOf(
"jpg",
"jpeg"
))
private static Set<String> arraySetOf(String... suffixes) {
return new ArraySet<>(Arrays.asList(suffixes));
}
}
有Kotlin基础的知道使用companion代替static,那么改成Kotlin代码后如下:
enum class MimeType() {
JPEG("image/jpeg", MimeType.arraySetOf(
"jpg",
"jpeg"
))
companion object {
private fun arraySetOf(vararg suffixes: String): Set<String> {
return ArraySet(listOf(*suffixes))
}
}
}
这样编译是没问题的,但是运行时却出了异常:
ClassNotFoundException, Could not initialize class
原因很简单,enum类初始化失败. 因为初始化实例时, companion object还没有初始化. 引用其字段, 导致NPE, 类初始化失败, 导致ClassNotFoundException, Could not initialize class.
所以就剩下三种方式解决:
- 该enum用java
- arraySetOf该伴身方法转移到另一个类
- 直接把ArraySet(listOf(*suffixes))套用上每个枚举
简单修改后
enum class MimeType() {
JPEG("image/jpeg", ArraySet(listOf(
"jpg",
"jpeg"
)))
}
kotlin刚学习没多久就碰到这种奇怪问题也实属不幸,可能因为kotlin跟java的一些概念不同,有更好的方式处理枚举吧
网友评论