Java基础_枚举类型


一、Java 5 之前定义”枚举类型”

Java 5之前是没有枚举类型的,在Java 5之前程序员们使用以下方式来解决与枚举类似的问题:

//定义‘枚举’类
class NUM{
	private NUM(){}	//私有化构造器
	private static final NUM ONE = new NUM();
	private static final NUM TWO = new NUM();
	private static final NUM THREE = new NUM();
	private static final NUM FORE = new NUM();
	//方法
	...
}
//调用
public class Test{
	public static void main(String[] args){
		NUM choose = NUM.ONE;
		//if(choose == new NUM()){		//私有化构造器为了防止这样的非法创建
		if(choose == NUM.ONE){
			System.out.println("NUM1");
		}else{
			System.out.println("NOT NUM1");
		}
	}
}
  • 在上面方法中使用私有化构造器是为了保护该枚举类,不让其他程序自己去使用 new 创建一个该类的对象。
  • 使用static 的 final的常量来做为成员,并为public 可由外部直接通过类名直接访问。
  • 因为所有的枚举都是常量,所以尽量使用大写来表示枚举类型。

二、Java 5之后的枚举类型

enum NUM{
	ONE,TWO,THREE,FORE;			//只可以写在枚举体的最开始的部分
	private NUM(){};			//构造器可以省略,如果写的话,必须为私有private
	//方法
	...
}

在底层,类似于上面 java 5之前 NUM类的实现,不过枚举自身带有许多的方法。

  • enum类型直接继承 java.lang.Enum 类,但是不能显式继承(即不能写成 enum NUM extends java.lang.Enum)。
  • enum 相当于一个类,可以有自己的构造器,成员变量,普通方法和抽象方法。
  • 默认为私有的构造方法,不可以改变。
  • 枚举实例必须位于枚举体最开始的部分,每个实例用‘,’分隔,最后使用‘;’与其他成员分隔。

三、 java.lang.Enum类原码分析

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
    //以下成员为 final  不可被重写覆盖的
    //===========================================
    //枚举常量名
    private final String name;
   	public final String name() {
        return name;
    }
    //枚举常量的下标
    private final int ordinal;
    public final int ordinal() {
        return ordinal;
    }
    //构造函数
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
	}
    // toString 方法,返回枚举常量名
     public String toString() {
        return name;
    }
    //equlse方法 ,直接比较两个枚举对象的地址,即比较两个枚举对象
    public final boolean equals(Object other) {
        return this==other;
    }
	/**
     * enum classes cannot have finalize methods.  不可以有finalize方法
     */
    protected final void finalize() { }
    ...
}

枚举相当于使用java.lang.Enum ,并在自身创建了很多自己的对象(结合上面的 一 和 二),它自己本身是个类,可以有自己的方法,成员等等。

【参考博客】https://blog.csdn.net/guohengcook/article/details/81277070

三、switch-case 与 枚举

1. switch-case

枚举只可以识别 int 类型,所支持的所有类型都是最终转化为 int

在java 5 之前

  • 只支持 byte,shot,char,int 基本数据类型。

在java 5之后

  • 由于自动拆箱的缘故,也支持上面四种基本类型的包装类。
  • 支持枚举类型。

在java 7 之后

  • 支持String类型,并使用HashCode去比较,又由于两个String的HashCode可能相同,在编译时,JVM会自动加上使用equlse再进行比较。

2. switch-case与枚举

枚举使用switch-case时,在编译时,会将枚举常量使用 ordinal() 方法转化为 int ,比较的是下标序号。

四、 枚举练习

1.枚举中的方法

public class TestEnum {
	public static void main(String[] args) {
		NUM[] nums = NUM.values();
		for (NUM num : nums) {
			System.out.println(num.ordinal() + "  " + num.name() + "  " + num);
		}
	}
}
enum NUM{
	ZERO("零"), ONE("壹"),TWO("贰");
	private final String name;
	NUM(String name) {
		this.name = name;
	}
	public String toString() {
		return name;
	}
}

运行结果
0 ZERO 零
1 ONE 壹
2 TWO 贰

2.枚举实现接口

枚举实例后带花括号,表示 其为匿名内部类对象。

测试1public class TestEnum {
	public static void main(String[] args) {
		NUM[] nums = NUM.values();
		for (NUM num : nums) {
			System.out.println(num.fun());
		}
	}
}
interface Interface {
	public String fun();
}
enum NUM implements Interface{
	ZERO, ONE,TWO;
	@Override
	public String fun() {
		return "Enum.NUM";
	}
}

运行结果:
Enum.NUM
Enum.NUM
Enum.NUM

测试2
public class TestEnum {
	public static void main(String[] args) {
		NUM[] nums = NUM.values();
		for (NUM num : nums) {
			System.out.println(num.fun());
		}
	}
}

interface Interface {
	public String fun();
}

enum NUM implements Interface {
	ZERO {
		@Override
		public String fun() {
			return "ZERO";
		}
	},
	ONE {
		@Override
		public String fun() {
			return "ONE";
		}
	},
	TWO {
		@Override
		public String fun() {
			return "TWO";
		}
	};
}

运行结果:
ZERO
ONE
TWO

发表评论

邮箱地址不会被公开。 必填项已用*标注

昵称 *