→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

<JDK1.5新特性>:5.枚举-

JDK 1.5加入了一个全新类型的“类”(与类、接口属于同一个层次)-- 枚举类型。为此JDK1.5引入了一个新关键字:enum

 一、枚举类型及其原理的介绍


1.我们可以这样定义和使用一个枚举类型,枚举名称一般使用大写方式:

定义:

public enum Color {
Red,
White,
Blue;
}

注:最后一个枚举类型值可加分号“;”也可不加。

使用:

Color myColor = Color.Red;

 


2.枚举类型还定义了两个有用的静态方法

 values()valueOf()

使用方式:
  values():

package cn.edu.bupt;

public class ColorTest {

/**
*
@param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for(Color myColor : Color.values()) {
System.out.println(myColor);
}
}

}

enum Color {
White,
Red,
Blue
}

 


3.枚举类型作为方法参数传入:

package cn.edu.bupt;

public class EnumTest {
public static void doOp(OpConstant opConstant) {
switch(opConstant) {
case TURN_LEFT: //此处不能使用OpConstant.TURN_LEFT 而只能写成TURN_LEFT,下同
System.out.println("向左转");
break;
case TURN_RIGHT:
System.out.println("向右转");
break;
case SHOOT:
System.out.println("射击");
break;
}
}

public static void main(String[] args) {
doOp(OpConstant.TURN_LEFT);
}
}

enum OpConstant {
TURN_LEFT,
TURN_RIGHT,
SHOOT;
}

注:switch语句中可用的数据类型:1、char;2、byte;3、short;4、int;5、enum;

而不能跟String、long等数据类型

使用if语句改写如下:

package cn.edu.bupt;

public class EnumTest {
public static void doOp(OpConstant opConstant) {
if(opConstant == OpConstant.SHOOT) { //可使用"=="
System.out.println("射击");
}
else if(opConstant.equals(OpConstant.TURN_LEFT)){ //可使用.equals()方法
System.out.println("向左转");
}
else {
System.out.println("向右转");
}
}

public static void main(String[] args) {
doOp(OpConstant.TURN_LEFT);
}
}

enum OpConstant {
TURN_LEFT,
TURN_RIGHT,
SHOOT;
}

 


 

4.枚举类型的本源:

  定义枚举类型时本质上就是在定义一个类别,只不过很多细节由编译器帮您完成了,

所以在某种程度上,enum关键字的作用就像是classinterface

  当使用“enum”定义枚举类型时,实质上定义出来的类型继承自java.lang.Enum类,

每个枚举的成员其实就是定义的枚举类型的一个实例(Instance),他们都被预设为

final所以我们无法改变他们,他们也是static成员,所以我们可以通过类型名称直接使用

他们,当然最重要的,他们都是public

  具体可看在JDK帮助文件中查看到java.lang.Enum

这是一个抽象类。在定义一个枚举类型的时候,他的本质就是一个类,这个是编译器自动完成相关继承细节的,

因此在定义枚举类型的时候,就是生成了一个类,并且它的每一个成员都是都是该类的一个实例:

public enum Color {
Red,
White,
Blue;
}

在Color这个枚举中,包含有三个实例对象,其名称分别是Red、White、Blue,他们在编译的时候就已经确定好了。

换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行时,我们

无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定了,也就是说我们不能使用new关键字

来生成新的对象。五十九-23:00

 


 

 对于枚举类型,不能从外部使用new关键字为枚举类型创建新的对象,因为创建对象的任务是有其成员负责,在写代码

时候,内部声明了几个成员,就已经生成了几个该枚举类型的实例对象,并且这些实例对象是在编译时确定的,这种情况

类似于单例模式五十九-23:00

因为枚举类型本身也是一个类,它会自动的继承自java.lang.Enum 所以,它也可以在内部去定义自己的成员变量、成员

方法,当然也可以定义自己的构造方法(构造方法不可继承)。

如下代码:

package cn.edu.bupt;

public enum Coin {
//枚举类的静态公有实例对象(public static final)
penny("hello"), nickel("hello"), dime("welcom");

//枚举类的成员变量
private String value;

//枚举类的构造方法
Coin(String value) {
this.value = value;
}

//枚举类的成员方法
public String getValue() {
return value;
}

public static void main(String[] args) {
Coin coin = Coin.penny;
System.out.println(coin.getValue());
}
}

说明:

  1、枚举类的构造方法一定是private访问权限,这个private可以显式写出,也可以省略,但是不可以

显式写成publicdefaultprotected;因为这里不能在枚举类的外部生成枚举类的实例对象;

  2、实例对象的生成都是在枚举类的内部,因为构造函数是私有的,实例对象名(引用名称)是成员名称;

  3、当有构造函数需要参数的时候,一定要在枚举类的内部定义成员的时候同时加入括号传入相应的参数,

参数的个数、类型一定要一致,否则会发生编译错误。如下图:

  4、不管是枚举还是普通的类,在生成实例对象的时候都需要调用构造方法,只不过一个是只能在类的内部

调用另一个是可以在类的外部进行调用。

  5、枚举类的写法:除了加入枚举类型特有的成员(如上图的penny、nickel、dime枚举类型成员)和私有

的构造方法外,其与的方法和变量写法与类完全一致。

  6、普通类与枚举类型的区别:枚举类型的对象是在编译的时候已经确定好了,并且在运行时是不能改变的;

而普通类的对象是在编译时不确定的,在运行时,理想状态下可以随意的创建对象;五十九-29:00

  7、因为枚举类内部的成员,是当前枚举类的实例对象,并且他们都是publicstaticfinal,因此他们

的引用方式是类似于Coin.penny这种形式。五十九-28:40

  8、在对枚举实例的引用方面与普通的类是相同的,如:coin.getValue()。

 

 二、枚举类型API的使用


 

 1、values()

静态方法;返回当前枚举类型的所有内部实例对象,并存放在一个该枚举类型的数组中,方便遍历;

Coin枚举类型定义如下:

package cn.edu.bupt;

public enum Coin {
//枚举类的静态公有实例对象(public static final)
penny("hello"), nickel("world"), dime("welcome");

//枚举类的成员变量
private String value;

//枚举类的构造方法
Coin(String value) {
this.value = value;
}

//枚举类的成员方法
public String getValue() {
return value;
}

public static void main(String[] args) {
Coin coin = Coin.penny;
System.out.println(coin.getValue());
}
}

Coin.values()测试:

package cn.edu.bupt;

public class EnumTest1 {
public static void main(String[] args) {
for(Coin coin : Coin.values()) { //将Coin中的每一个实例对象放在Coin[]数组对象中,对该数组进行遍历
System.out.println(coin);
}
}
}

测试结果是:


 

2、valueOf(String name)

静态方法;该方法通过传递进去的枚举类型对象实例名称(String类型),返回该枚举类型的指定实例对象;

package cn.edu.bupt;

public class EnumTest1 {
public static void main(String[] args) {
System.out.println(Coin.valueOf("penny")); //若不存在指定的实例对象将会抛出异常
}
}

 


3、compareTo(Enum)

普通方法;枚举类型实例之间的位置的比较,如下例:

package cn.edu.bupt;

public class EnumTest1 {
public static void main(String[] args) {
System.out.println(Color.Blue.compareTo(Color.valueOf("Pink"))); //枚举类型成员在类型内部位置之间的比较,而不是普通字符串之间的比较
}

private enum Color {
Red, Blue, Pink;
}
}

结果:

-1


 

4、ordinal()

返回当前实例在整个枚举类型中的次序;

package cn.edu.bupt;

public class EnumTest1 {
public static void main(String[] args) {
for(Color color : Color.values()) {
System.out.println(color.ordinal() + " " + color.name());
}
}

private enum Color {
Red, Blue, Pink;
}
}

结果:

 

posted on 2012-02-03 01:13  阿童沐  阅读(378)  评论(0)    收藏  举报