昨天晚上在给Struts2的Action写测试代码的时候,需要用到enum,就研究了一下。
先是enum的代码:
代码段1:
public enum ActionResult {
SUCCESS("success"),
NONE("none"),
ERROR("error"),
INPUT("input"),
LOGIN("login");
private String value;
private ActionResult(String value){
this.value = value;
}
/**
* 返回常量值
* @return 常量值
*/
public String getValue(){
return value;
}
}
试着输出ActionResult.SUCCESS:
System.out.println(ActionResult.SUCCESS);
结果:
引用
SUCCESS
输出ActionResult.SUCCESS.getClass():
System.out.println(ActionResult.SUCCESS.getClass());
结果:
引用
class net.javayuan.blog.constant.ActionResult
给ActionResult加上main方法,检查ActionResult的类型:
public enum ActionResult {
SUCCESS("success"),
NONE("none"),
ERROR("error"),
INPUT("input"),
LOGIN("login");
private String value;
private ActionResult(String value){
this.value = value;
}
/**
* 返回常量值
* @return 常量值
*/
public String getValue(){
return value;
}
public static void main(String[] args){
Class<?> clazz = ActionResult.class;
Class<?> superClass = clazz.getSuperclass();
Class<?>[] interfaces = clazz.getInterfaces();
System.out.println(clazz);
System.out.println(superClass);
System.out.println(interfaces.length);
}
}
输出:
引用
class net.javayuan.blog.constant.ActionResult
class java.lang.Enum
0
结论:1、enum关键字定义的枚举类型的直接父类都是java.lang.Enum。至于Enum的父类,查查API文档就知道了:Enum的父类是Object。
2、enum关键字定义的枚举类型没有直接实现任何接口。查了API文档,Enum实现了Serializable接口跟Comparable接口。
已知:ActionResult.SUCCESS.getClass().toString()的结果是"class net.javayuan.blog.constant.ActionResult",
并且ActionResult的父类是Enum,接着来看看为什么System.out.println(ActionResult.SUCCESS);输出"SUCCESS"。
打开java.lang.Enum的源代码,查找关键字“public String toString()”,找到代码:
public String toString() {
return name;
}
name的定义:
private final String name;
name的赋值在Enum的protected构造方法中执行:
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
给ActionResult的main方法中添加一句代码:System.out.println(ActionResutl.SUCCESS)
public static void main(String[] args){
Class<?> clazz = ActionResult.class;
Class<?> superClass = clazz.getSuperclass();
Class<?>[] interfaces = clazz.getInterfaces();
System.out.println(clazz);
System.out.println(superClass);
System.out.println(interfaces.length);
System.out.println(ActionResult.SUCCESS);
}
在Enum的构造方法处和ActionResult的main方法处同时设置断点,检查Enum的构造是在什么时候执行。结果用Eclipse调试的时候意外的发现,Enum的构造在main方法执行之前。查看Enum构参数中name和ordinal的值,居然name为null,那toString中的name是怎么来的?继续调试,发现执行完this.name = name;之后,参数列表中的name跟Enum中的name同时变成了"SUCCESS",这个值是怎么来的,我也无从查证,因为构造Enum时,参数name居然是未知的,我只能猜测是JVM对Enum进行了特殊处理。再调试了几遍,发现第二个构造参数ordinal也一样(它也是Enum类的一个私有int常量),执行this.ordinal = ordinal;之后,它的值才确定。按F7跳出Enum的构造方法,结果跳到ActionResult的构造方法里,检查参数value,值为"success"。按F7,跳到了SUCCESS("success");这一行。按F5,发现SUCCESS("success")刚执行完毕,原来刚刚的动作是对SUCCESS进行初始化。现在箭头指在NONE("none")这一行,按F5,进入ActionResult构造方法,再按F5,进入了Enum构造方法,执行完Enum的构造,检查一下ordinal的值,为1。初始化ERROR时,ordinal为2。
结论:
1、SUCCESS、NONE等静态变量是常量;
2、ActionResult的构造是在对常量SUCCESS、NONE等进行初始化时执行,每个常量都是一个ActionResult实例;
3、ActionResult构造之前会调用Enum的构造方法,对Enum进行构造(看来之前写的
关于构造方法对enum不适用);
4、构造Enum时,参数name和ordinal的值都是未知的,name值似乎是来自常量名,ordinal从0开始递增,ordinal具体作用目前不明;
翻了Thinking In Java 4th Edition:
引用
ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。
引用
values()是由编译器添加的static方法。可以看出,在创建Explore的过程中,编译器还为其添加了valueOf()方法。这可能有点令人迷惑,Enum类不是已经有valueOf()方法了吗。不过Enum中的valueOf()方法需要两个参数,而这个新增的方法只需要一个参数。
分享到:
相关推荐
2. **枚举类型(Enum)**:JDK 5之前,枚举通常通过常量类来实现,而JDK 5引入了正式的枚举类型,使得枚举更加安全、易用且富有表现力。例如,`enum Color { RED, GREEN, BLUE }`。 3. **泛型(Generics)**:泛型...
在JDK 5之前,Java没有内置的枚举类型,开发者通常通过创建final类和static final变量来模拟枚举。JDK 5引入了enum关键字,使得枚举更安全、更易于使用,同时也支持枚举的继承和方法。 3. **泛型(Generics)**: ...
枚举类型允许创建一组相关的常量,提高了代码的可读性和安全性。枚举不仅可以包含常量,还可以定义方法和字段,甚至实现接口。 增强的for循环(也称为foreach循环)是JDK 5中的一个语法糖,它简化了遍历数组和集合...
在本文中,我们将深入探讨枚举类型及其在JDK中的应用。 一、枚举的定义与使用 1. 基本定义:枚举在Java中通过`enum`关键字定义。例如,创建一个表示一周天的枚举类型: ```java public enum DayOfWeek { MONDAY, ...
- **枚举(Enums)**:枚举是一种预定义常量的类型,增强了枚举类型的使用,使其更像一种类。 - **自动装箱/拆箱(Autoboxing and Unboxing)**:自动装箱将基本类型与对应的包装类之间进行转换,简化了代码。 - ...
之前,Java中的常量通常通过final static变量实现,而JDK5引入了枚举类型,使得常量管理更加规范和安全。枚举可以包含方法和字段,甚至实现接口,提高了代码的结构化程度。 3. **自动装箱与拆箱(Autoboxing and ...
JDK5中引入的枚举类型是Java对常量集合的标准化处理。枚举可以看作是一种特殊的类,它限制了实例的创建,通常用于定义一组固定的常量。例如: ```java public enum Color { RED, GREEN, BLUE; } ``` 三、变量注解...
3. **枚举类型(enum)**:增强了枚举的使用,使其成为一种强大的数据类型,支持比较、遍历等操作。 4. **变量作用域增强(for-each循环)**:简化了迭代集合或数组的代码,提高了可读性。 5. **Static imports**:...
3. **枚举类型增强**:新增了`enumSet`和`enumMap`数据结构,专门用于枚举类型的集合操作,提高了效率和代码的清晰度。 4. **动态代理改进**:JDK1.6增强了动态代理的实现,允许在运行时创建接口的代理类,这对于...
9. **枚举**:Java 5引入的枚举类型,用于表示有限集合的常量,提供了一种类型安全的方式来创建有限的、不可变的类实例。 10. **注解**:`java.lang.annotation`包中的注解(Annotation)是一种元数据,可以为...
2. **枚举类型(Enum)的增强**:在JDK 6中,枚举类型被赋予了更多的功能,如可以拥有方法和字段,可以实现接口,甚至可以定义枚举常量之间的关系。这极大地提高了枚举的可读性和可维护性。 3. **可变参数(Varargs...
2. **枚举类型**:在JDK 5.0之前,Java使用整数常量或自定义类来表示枚举。5.0版本引入了内置的枚举类型,使得枚举更加规范,支持方法和常量,增强了可读性和可维护性。 3. **自动装箱/拆箱**:Java 5.0实现了基本...
5. **枚举类型**:这是Java语言的一个重大改进,允许开发者定义自己的枚举类型,增强了代码的可读性和安全性。 6. ** assert 关键字**:Java 1.4引入了断言机制,便于开发人员进行单元测试和调试。 7. **改进的...
Java Development Kit (JDK) 5是Java编程语言的一个重要版本,由Sun Microsystems(后被Oracle公司...阅读JDK 5中文文档,可以深入了解这些特性的具体用法和背后的设计理念,对于学习和理解Java编程具有重要的价值。
3. **枚举类型**:JDK5.0之前,枚举通常通过常量类来实现,而JDK5.0引入了内置的枚举类型,提供了更强大的功能和更好的类型安全。枚举可以有方法、构造函数,甚至可以实现接口,例如 enum Color {RED, GREEN, BLUE}...
3. 枚举类型(Enums):JDK5.0引入了枚举类型,使得常量的定义更加规范,支持更多的面向对象操作,如比较、遍历等。 4. 可变参数(Varargs):使用省略号“...”表示可变参数,允许一个方法接受任意数量的同类型...
11. **JDK6的新特性**:可能包括增强的for循环(foreach)、可变参数、枚举类型、泛型、注解(Annotation)等。 12. **实例代码**:每个知识点通常会搭配示例代码,帮助读者理解和实践,提高编程能力。 这个学习...
9. **枚举和注解**:枚举类型的定义和使用,注解的创建和应用,元注解的理解。 10. **Swing GUI**:构建图形用户界面的基础,包括组件使用,布局管理器,事件监听等。 11. **JDBC**:数据库连接,预编译SQL语句,...
Java 5引入了许多重要的新特性,如泛型、枚举、自动装箱拆箱、可变参数、增强的for循环(foreach)、类型推断(`varargs`)等。源码分析可以帮助开发者深入理解这些特性的实现机制,提升编程效率。 2. **Java 6...
其次,JDK5引入了枚举类型(enum)。枚举是一种特殊的类,用于定义一组固定数量的常量。这比传统的final常量更安全,因为枚举不允许实例化,从而防止了可能出现的未定义枚举值。 另外,JDK5增加了泛型(Generics)...