`

学习JDK5的枚举类型

    博客分类:
  • Java
阅读更多
昨天晚上在给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()方法需要两个参数,而这个新增的方法只需要一个参数。
分享到:
评论

相关推荐

    Java JDK 5.0学习笔记(第二部分)

    本书是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型、J2SE中标准的API...

    良葛格Java JDK 5.0学习笔记

    本书是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型、J2SE中标准的API...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

     《Java JDK 7学习笔记》详细介绍了JVM、JRE、Java SE API、JDK与IDE之间的对应关系。必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。  《Java JDK 7学习笔记》将IDE操作纳为教学内容...

    Java学习笔记7.0

    《Java JDK6学习笔记》是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型...

    Java JDK 5.0学习笔记(第一部分)

    本书是作者良葛格本人近几年来学习Java的心得笔记,结构按照作者的学习脉络依次展开,从什么是Java、如何配置Java开发环境、基本的Java语法到程序流程控制、管理类文件、异常处理、枚举类型、泛型、J2SE中标准的API...

    回顾 Java SE 基础实现代码 Java学习资料 自学资料

    回顾 Java SE 基础,基于 jdk-1.8 实现代码。 目录 语言基础 (八大)基本类型与引用类型 类型转换 运算符 流程控制 字符串与数组 核心技术 抽象 类的高级特性 final 内部类 枚举与泛型 异常处理 集合 I/O 反射 多...

    J2SE技术总结-Java学习精华教程-电子书

    变量与数据类型 ..........标识符 ..........运算符 ..........控制台输入输出 ..........流程控制 ..........数组的使用 .....字符串和正则表达式 ..........字符串 ..........正则表达式 .....类和对象 .............

    Java学习路线:day22

    文章目录第10章枚举类与注解枚举类的使用枚举类的理解自定义枚举类使用enum关键字定义枚举类Enum类中的常用方法使用enum关键字定义的枚举类实现接口注解的使用注解的理解Annotation的使用示例如何自定义注解jdk中4个...

    Java-notes:Java 知识梳理和学习笔记,计算机网络,数据结构,设计模式等

    Java 的学习笔记和整理的知识点,包含Java语言基础、Java服务端方向的框架、设计模式、计算机网络、算法、Java 虚拟机和数据库等多个方面的内容。想了解前端的内容参考,Android相关的内容参考。 目录结构 语言基础...

    疯狂JAVA讲义

    学生提问:老师,我想学习Java编程,到底是学习Eclipse好呢,还是学习JBuilder好呢? 21 1.9 本章小结 22 本章练习 22 第2章 理解面向对象 23 2.1 面向对象 24 2.1.1 结构化程序设计简介 24 2.1.2 程序的三种...

    Java开发技术大全(500个源代码).

    示例描述:本章学习运行时类型识别。 Candy.java 一个用来测试的简单类 changeFields.java 改变属性值示例 Circle.java 一个用于测试的简单类 DumpMethods.java 使用反射机制来获取类中的方法 getClassName....

    21天学通Java-由浅入深

    图文并茂很适合初学着学习 下面是课程的目录: 第一篇 基础篇 第1章 Java简介(精彩视频:33分钟) 21 1.1 Java的平台简介 21 1.2 安装工具包 22 1.2.1 下载JDK 22 1.2.2 安装JDK 24 1.2.3 查看与设置环境变量 25 ...

    java进阶技术:泛型、反射、注解

    泛型是Java SE 1.5的新特性,好处是在...注解(Annotation)是JDK1.5及以后引入的新特性,与类、接口、枚举是在同一个层次。可声明在包、类、字段、方法、局部变量、方法参数等前面,用来对这些元素进行说明,注释。

    Thinking in Java简体中文(全)

    D.2.2 JDK性能评测[2] D.2.3 特殊工具 D.2.4 性能评测的技巧 D.3 提速方法 D.3.1 常规手段 D.3.2 依赖语言的方法 D.3.3 特殊情况 D.4 参考资源 D.4.1 性能工具 D.4.2 Web站点 D.4.3 文章 D.4.4 Java专业书籍 D.4.5 ...

    Java并发编程(学习笔记).xmind

    是一个枚举,表示 keepAliveTime 的单位(有NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS,7个可选值 线程的创建与销毁 管理队列任务 饱和策略 AbortPolicy ...

    【Java设计模式】你对单例模式了解多少,一文深入探究

    不让第二步和第三步重排序-DoubleCheck方案二:基于类初始化-静态内部类饿汉式饿汉式与懒汉式最大区别序列化破坏单例模式原理枚举单例基于容器的单例模式基于TreadLocal线程单例源码分析-JDK源码分析-spring其他相关...

    java 编程入门思考

    D.2.2 JDK性能评测[2] D.2.3 特殊工具 D.2.4 性能评测的技巧 D.3 提速方法 D.3.1 常规手段 D.3.2 依赖语言的方法 D.3.3 特殊情况 D.4 参考资源 D.4.1 性能工具 D.4.2 Web站点 D.4.3 文章 D.4.4 Java专业书籍 D.4.5 ...

    Java 高级特性.doc

    5、泛型的参数类型还可以是通配符类型。例如Class&lt;?&gt; classType = Class.forName(java.lang.String); 例子: a..使用?通配符可以引用其他各种参数化的类型,但不能调用与参数化有关的方法; Collection&lt;?&gt; c = new ...

    Thinking in Java(中文版 由yyc,spirit整理).chm

    D.2.2 JDK性能评测[2] D.2.3 特殊工具 D.2.4 性能评测的技巧 D.3 提速方法 D.3.1 常规手段 D.3.2 依赖语言的方法 D.3.3 特殊情况 D.4 参考资源 D.4.1 性能工具 D.4.2 Web站点 D.4.3 文章 D.4.4 Java专业书籍 D.4.5 ...

Global site tag (gtag.js) - Google Analytics