关注一下嘛,又不让你背锅!

问:Java 枚举类可以继承其他类(或实现其他接口)或者被其他类继承吗,为什么?
答:枚举类可以实现其他接口但不能继承其他类,因为所有枚举类在编译后的字节码中都继承自 java.lang.Enum(由编译器添加),而 Java 不支持多继承,所以枚举类不可以继承其他类。
枚举类不可以被继承,因为所有枚举类在编译后的字节码中都是继承自 java.lang.Enum(由编译器添加)的 final class 类,final 的类是不允许被派生继承的。(不清楚的可以查看前一篇历史推送枚举原理题)
问:Java switch 为什么能使用枚举类型?
答:Java 1.7 之前 switch 参数可用类型为 short、byte、int、char,枚举类型之所以能使用其实是编译器层面实现的,编译器会将枚举 switch 转换为类似 switch(s.ordinal()) { case Status.START.ordinal() } 形式,所以实质还是 int 参数类型,感兴趣的可以自己写个使用枚举的 switch 代码然后通过 javap -v 去看下字节码就明白了。
此问题延伸出一个新问题就是 JDK 1.7 中 switch 支持 String 类型参数的原理是什么?
实际上 JDK1.7 的 switch 支持 String 也是在编译器层面实现的,在 Java 虚拟机和字节代码层面上依然只支持在 switch 语句中使用与整数类型兼容的类型。我们在 switch 中使用的 String 类型在编译的过程中会将字符串类型转换成与整数类型兼容的格式(譬如基于字符串常量的哈希码等),不同的 Java 编译器可能采用不同的方式和优化策略来完成这个转换。
问:Java 枚举会比静态常量更消耗内存吗?
答:会更消耗,一般场景下不仅编译后的字节码会比静态常量多,而且运行时也会比静态常量需要更多的内存,不过这个多取决于场景和枚举的规模等等,不能明确的定论多多少(一般都至少翻倍以上),此外更不能因为多就一刀切的认为静态常量应该优于枚举使用,枚举有自己的特性和场景,优化也不能过度。我们在上一篇枚举实质原理中已经解释了每个枚举类中的具体枚举类型都是对应类中的一个静态常量,该常量在 static 块中被初始实例化,此外枚举类还有自己的一些特有方法,而静态常量实质却很简单,所以从对象占用内存大小方面来计算肯定是枚举类比静态常量更加占体积和消耗运行时内存,至于具体怎么算其实很简单,大家可以自己下去搜一下 java 对象占用内存大小即可了解更多,搞清楚特定场合下具体大多少没有什么实际意义,搞清楚为什么大和怎么算出来的本质原因即可。
题外话:这是个在 Android 圈子里很有意思且很有争议的问题,其实我也是 Android 开发,但是我们项目中依然有在使用枚举,也有在使用静态常量 BitMask 加注解限制,枚举相对静态常量在理论层面或大量枚举类型层面是存在一些性能问题(低版本安卓系统上没有很好的优化),但是在需要枚举特性的场合下使用利是大于弊的,就好比大家都知道 01101101 这种二进制效率更高,你为什么不直接用二进制写代码呢,所以在 Android 中不要再说到枚举就一刀切说不建议使用,而应该说如果需要用到枚举特性的情况下不禁止使用枚举,不需要用到枚举特性的场合下使用静态常量是会节约内存空间;此外使用枚举在一些场景下是可以通过混淆替换成 int 的(具体可以参见 Proguard 官方文档 https://www.guardsquare.com/en/proguard/manual/optimizations),默认枚举是不混淆的。
放大招镇压(【原文翻墙】https://plus.google.com/+DianneHackborn/posts/YDykw2hstUu):

简单概括就是说不要过度优化,作为 JVM 开发者如果让 Java 的 enum 开销大到让一般应用都不敢用则说明这个特性的设计完全是彻底失败了,依据自己的场景进行适度的选择才是最好的,不要一刀切。
当然你可以继续去爆栈上面找这个 topic 的乐趣:
https://stackoverflow.com/questions/5143256/why-was-avoid-enums-where-you-only-need-ints-removed-from-androids-performanc
https://stackoverflow.com/questions/4822877/why-doesnt-android-use-more-enums
戛然而止!这是 Part 2 部分,Part 3 部分请下周一准时抄收(枚举收官)~~
老铁们,别嫌短,长了你肯定不会看完的,所以这就是码农每日一题的宗旨(其他历史文章请查看公众号历史记录),周末了,下周一早晨见~
看完分享一波嘛,和你的小伙伴一起讨论才更加有意思,右上角分享
666~

看个笑话放松一下
假如生活欺骗了你,找50个程序员问问为什么编程;
假如生活让你想死,找50个程序员问问BUG改完了没有;
假如你觉得生活拮据,找50个程序员问问工资涨了没有;
假如你觉得活着无聊,找50个程序员问问他们一天都干了什么!
Before you talk, listen; before you react, think; before you spend, earn; before you quit, try.
在你说话之前,先听;在你回应之前,先想;在你消费之前,先挣;在你退出之前,先试。