1.枚举类型是做了特殊限制的类,在Class文件格式中的变化是添加了值为0x4000的属性标记ACC_ENUM,同时添加的还有值为0x2000的ACC_ANNOTATION。这些变化是[JVMS:99]之后的05年做出的,这里是对[JVMS:99]的官方修改说明。
2.枚举类型不能由程序员来显式实例化,这来自使用枚举的初衷(即语义上不允许)。而语法上的不允许,则由如下4点保证:a.编译器强制其构制造函数一定是private修饰符,以保证其不被类外实例化。类内的实例化亦不被允许,实例化的尝试会导致编译器报错。b.继承自Enum的final修饰的clone()方法是固定写好了的。c.序列化技术队枚举做了特殊处理。d.反射中对枚举类型的实例化会得到运行时错误。翻译自[JLS:05],Page249。
3.试图为枚举类型的写finalize()方法将导致编译器错误,因为枚举常量永远不会被垃圾回收。翻译自[JLS:05],Page250。
4.任何枚举类型的(隐式)直接父类都是java.lang.Enum<E>,E是由程序员自己定义的枚举类型。可以注意到Enum类自身的声明:
public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable
除此以外,我们注意到其声明了以下方法(忽略从Object类继承来的众多方法):
Class<E> getDeclaringClass();
// Returns the Class object corresponding to this enum constant's enum type.
String name();
// Returns the name of this enum constant, exactly as declared in its enum declaration.
int ordinal();
// Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero).
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name);
// Returns the enum constant of the specified enum type with the specified name.
参考自:[JDK API:05]
5.自己定义的枚举类型E,编译器会为程序员生成以下方法,并且不允许程序员自己写一个方法签名相同的方法,从而保证了以下方法行为的正确:
public static E[] values();
public static E valueOf(String name);
而且,其方法实现及与Enum类之联系由如下示例说明:
public enum Season{
SPRING,SUMMER, AUTUMN,WINTER;
}
上述定义的枚举类Season实际被javac修改如下:
public enum Season extends Enum<Season> {
public static final SPRING = new Season("SPRING", 0);
public static final SUMMER = new Season("SUMMER", 1);
public static final AUTUMN = new Season("AUTUMN", 2);
public static final WINTER = new Season("WINTER", 3);
/*synthetic*/ private static final Season[] $VALUES = new Season[]{Season.SPRING , Season.SUMMER , Season.AUTUMN , Season.WINTER };
public static Season[] values() {
return (Season[])$VALUES.clone();
}
public static Season valueOf(String name) {
return (Season)Enum.valueOf(Season.class, name);
}
private Season(/*synthetic*/ String $enum$name, /*synthetic*/ int $enum$ordinal) {
super($enum$name, $enum$ordinal);
}
}
示例参考自How is values() implemented for Java 6 enums
6.switch语句对于枚举类型的支持在下面做了说明。对于这样的代码:
public class Test
{
static enum Type
{
A, B;
}
public static void main(String[] args)
{
Type t = Type.valueOf(args[0]);
switch (t)
{
case A:
System.out.println("We've got A");
break;
case B:
System.out.println("We've got B");
break;
}
}
}
将被javac改写为如下代码:
public class Test
{
static enum Type
{
A, B;
}
private static int[] $SWITCH_TABLE$Test$Type;
static int[] $SWITCH_TABLE$Test$Type()
{
if (Type.$SWITCH_TABLE$Test$Type != null)
return $SWITCH_TABLE$Test$Type;
else
{
int[] is = new int[Type.values().length];
is[Type.A.ordinal()] = 1;
is[Type.B.ordinal()] = 2;
$SWITCH_TABLE$Test$Type = is;
return is;
}
}
public static void main(String[] args)
{
Type t = Type.valueOf(args[0]);
int[] is = $SWITCH_TABLE$Test$Type();
int i = is[t.ordinal()];
switch (i)
{
case 1:
System.out.println("We've got A");
break;
case 2:
System.out.println("We've got B");
break;
}
}
}
其中我们需要注意两点:
a.既然字节码采用的是tableswitch,那直接用Type.ordinal()返回的0~n-1作为tableswitch的下界和上界似乎更合理。但是,因为switch语句中的case标签的顺序可以不按照ordinal()的顺序写出,而为了case中的具体语句(上例为输出"We've got A"和"We've got B")的顺序不变,所以采用了int[]类型的$SWITCH_TABLE$Test$Type作为中间过渡。有意思的是,javac为这个field和另一个method使用了相同的名称,不要看的迷迷糊糊,:)
b.虽然这里是final static的常量,但是在case标签里面却不能像我们使用其他常量那样使用全额限定名:Test.Type.A或者Test.Type.B,而必须简写为A或者B。注意,这不是一个错误或者失误,以后亦不会做出改变。这个是有意思的一个讨论,原因请参考官方的回应。
分享到:
相关推荐
java枚举小例子,简单了解枚举的用法,适合初学者使用。
java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” </#list>
java 通过反射获取枚举类,及枚举类的值,枚举类枚举实例名。本项目为普通java项目
使用JDK1.6编写的枚举例子,里面有详细的注释,很有必要参考下
列举java 枚举相关信息列举java 枚举相关信息列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息
【Java面试】枚举从使用到原理
JAVA的枚举实例以及应用
java中enum枚举的详细用法。 0.0
JAVA枚举JAVA枚举
java高级编程 Enum枚举 包括枚举的例子,问题 及一些文档,是复习的好资源
java枚举状态机
java 枚举ppt 枚举定义 用普通类模拟枚举 带构造方法的枚举 带抽象方法的枚举 单例与枚举 枚举与类集
简单总结java枚举类型,适合java初学者
Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类...
我想几乎每一个学习Java语言的人在学习枚举的时候首先的一个疑问就是“为什么不用static final字段替代?”,有这个疑问就说明你已经摸索到了枚举类型的最主要功能......
一个关于JAVA枚举类型的MHT文件,包含JAVA枚举类型的用法,以及JDK版本的问题。
java枚举类型的说说明,详细阐述了枚举类型的使用和注意事项
理解java枚举类型
Java关于中文乱码问题的多种解决方法,中文乱码过滤器
java基础,反射枚举基础,自己总结的笔记。