1. JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enum. 我们可以这样来定义一个枚举类型
public enum Color {
Red, White, Blue
}
然后可以这样来使用Color myColor = Color.Red.
Eclipse 中新建一个enum,写一个简单的枚举
定义一个enum:
package com.ahuier.jdk5; public enum Color { Red, white, Blue }
定义一个操作enum 的类
package com.ahuier.jdk5; public class ColorTest { public static void main(String[] args) { Color myColor = Color.white; System.out.println(myColor); } }
2. 枚举类型还提供了两个有用的静态方法values()和valueOf().我们可以很方便地使用它们,例如
for (Color c : Color.values())
System.out.println(c);
定义一个枚举enum:
package com.ahuier.jdk5; public enum Color { Red, white, Blue, black }
定义一个操作enum的类:
package com.ahuier.jdk5; public class ColorTest { public static void main(String[] args) { Color myColor = Color.white; System.out.println(myColor); System.out.println("-------------"); /* * 调用Color.values()返回一个Color[]类型的数组,所以我们可以遍历它 */ for(Color color : Color.values()){ System.out.println(color); } } }
编译执行结果:white
-------------
Red
white
Blue
black【说明】:这边输出的都是按变量的定义的顺序输出的,本质上枚举定义是一个数组。
[values()是每个枚举类型都有的一个方法,它会得到我们所定义的枚举值的数组,遍历这个数组得出结果]
第二个例子:
package com.ahuier.jdk5; public class EnumTest { public static void doOp(OpConstant opConstant){ /* * 复习以前所讲内容switch()里面可以介绍的参数就只有四个,再加今天所学的enum类型,总共五种 * switch()里面介绍的参数是char, byte, short, int是四种。再加一个枚举enum */ switch(opConstant){ case TURN_LEFT: System.out.println("<--"); case TURN_RIGHT: System.out.println("-->"); case SHOOT: System.out.println("shoot"); } } public static void main(String[] args) { doOp(OpConstant.SHOOT); } } /* * 定义一个枚举 */ enum OpConstant{ TURN_LEFT, TURN_RIGHT, SHOOT //注意这边定义枚举最后分号 ; 可以加也可以不加都是对的。 }
编译执行 结果:shoot
第三个例子:
package com.ahuier.jdk5; public enum Coin { Penny("hello"), nickel("world"), dime("welcome"), quarter("hello world"); private String value; public String getValue(){ return value; } //定义枚举的构造方法 Coin(String value){ this.value = value; } public static void main(String[] args) { Coin coin = Coin.quarter; //由于枚举是static,final,的所以可以直接用类名去调用 System.out.println(coin); System.out.println(coin.getValue()); //取出其字符串值 } }
编译执行结果:quarter
hello world【说明】:我们开一下枚举的本源是什么:
1. 定义枚举类型时本质上就是在定义一個类别,只不过很多细节由编译器帮您完成了,所以某些程度上,enum关键字的作用就像是class或interface。
2. 当您使用“enum”定义 枚举类型时,实质上您定义出來的类型继承自 java.lang.Enum 类型,而每个枚举的成员其实就是您定义的枚举类型的一個实例(Instance),他们都被预设为 final,所以您无法改变他们,他们也是 static 成員,所以您可以通过类型名称直接使用他们,当然最重要的,它們都是公开的(public)。
查看JDK Doc文档中Enum:
public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable
This is the common base class of all Java language enumeration types. [Java enum 类型的基类]从这边可以知道我们所有定义的 enum 虽然是枚举,但是都是集成了这个基类 java.lang.Enum(它是一个抽象类)。查看它的一些方法,其中有一个方法是valueOf()方法是将一个字符串转换成一个枚举。
【总结】1. 枚举(Enum):我们所定义的每个枚举类型都继承自 java.lang.Enum 类,枚举中的每个成员默认都是public static final的。
2. 而每个枚举的成员其实就是您定义的枚举类型的一個实例(Instance)。换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。
在前面的程序中:
public enum Color {
Red, white, Blue, black
}这里面定义的enum Color有四个成员,表示这个枚举只有四个对象,在我们定义的类的是一般是new一个就生成一个实例,而在这个枚举中,你定义几个枚举值,就表示Color有几个实例,也就是有四个对象,这四个对象在编译的时候就已经确定好了,所以枚举的本源就是在编译的时候就已经确定好实例了。这些实例的对象名字叫什么等信息。
3. 枚举的比较
程序一:定义一个枚举,如上程序EnumTest.java
程序二:定义一个操作枚举的类
package com.ahuier.jdk5; public class ShowEnum { public static void main(String[] args) { /* * 将OpConstant里面的TURN_LEFT, TURN_RIGHT, SHOOT里面传递过来的字符串转换为一个枚举 */ enumCopareTo(OpConstant.valueOf(args[0])); //valueOf()将枚举OpConstant里面的字符串装换为一个枚举 } /* * 将传递过来的枚举值与OpConstant中的每一个值进行比较 */ public static void enumCopareTo(OpConstant constant){ System.out.println(constant); for(OpConstant c : OpConstant.values()){ System.out.println(constant.compareTo(c)); } } }编译传递一个参数 SHOOT 执行:SHOOT
2
1
0
【说明】:2表示SHOOT与枚举参数里面 TURN_LEFT 比较排后面两位,1表示SHOOT与枚举参数里面 TURN_RIGTH 比较排后面1位,2表示SHOOT与枚举参数里面 与自己SHOOT 比较并列。程序三:
package com.ahuier.jdk5; public class ShowEnum2 { public static void main(String[] args) { for(OpConstant c : OpConstant.values()){ //引用C语言中的输出 %d:按十进制输出; %s:按字符串输出; %n:回车 System.out.printf("%d, %s, %n", c.ordinal(), c); } } }编译执行结果:0, TURN_LEFT,
1, TURN_RIGHT,
2, SHOOT,【说明】查看JDK Doc 的ordinal()方法的说明(了解一下就行):返回一个枚举常量的顺序,第一个常量分配0,后面就是1,2,3,4...
一般用在复杂的EnumSet和EnumMap里面。
4. 枚举中的集合:EnumSet
EnumSet的名称说明了其作用,它是在J2SE 5.0后加入的新类别,可以协助您建立枚举值的集合,它提供了一系列的静态方法,可以让您指定不同的集合建立方式。
查看JDK Doc文档中的EnumSet
java.util
Class EnumSet<E extends Enum<E>>查看其方法可以知道,它的一些方法与我们的HashSet等的方法差别比较大,原因是枚举的是性质决定,枚举是一个在编译时期就确定对象的,不想普通对象一样可以随便生成的。而集合不同。
程序一:
package com.ahuier.jdk5; import java.util.EnumSet; import java.util.Iterator; enum FontConstant { Plain, Blod, Italilc, Hello } public class EnumSetDemo{ public static void main(String[] args) { /* * 为什么说EnumSet的初始化方式与普通的集合初始化方式不一样,其实本身是有枚举的性质来决定的 * 枚举的对象是固定,不像其他集合,想生成几个就生成集合 */ //of()里面介绍不同数量的参数,它表示打印枚举 集合中的的对象 EnumSet<FontConstant> enumSet = EnumSet.of(FontConstant.Plain, FontConstant.Blod); showEnumSet(enumSet); System.out.println("------------"); //complementOf()互补的,表示打印为进行初始化的枚举的集合中的对象,这边打印出Plain和Bload的另外两个枚举对象 showEnumSet(EnumSet.complementOf(enumSet)); } public static void showEnumSet(EnumSet<FontConstant> enumSet){ /* * enumSet 继承了集合,便继承了Iterator()方法 */ for(Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();){ System.out.println(iter.next()); } } }
编译执行结果:Plain
Blod
------------
Italilc
Hello程序二:
package com.ahuier.jdk5; import java.util.EnumSet; import java.util.Iterator; public class EnumSetDemo2 { public static void main(String[] args) { /* * noneOf() 创建一个空的枚举集合,开始是空的,并指定接受什么类型的枚举 * 这边可以接受FontConstant的枚举 */ EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class); //使用add()添加FontConstant类型的枚举 enumSet.add(FontConstant.Blod); enumSet.add(FontConstant.Italilc); showEnumSet(enumSet); } public static void showEnumSet(EnumSet<FontConstant> enumSet){ /* * enumSet 继承了集合,便继承了Iterator()方法 */ for(Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();){ System.out.println(iter.next()); } } }
编译执行结果:Blod
Italilc