JavaSE第五十九讲:类型安全的枚举

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值