第一次使用markdown写文章,还没弄懂,以后慢慢调整吧。
首先,不得不承认我是懒的,懒到2年之后才认真的看看enum的用法。
记得2年前工作中看到enum,当时便随便去网上查看用法,没看懂,便放过去了,因为可以随便修改原来的代码,达到项目目的。
其实没看懂是正常的,enum的类的写法便和java普通类的写法不同。这次仔细参看了多个blog(链接附在后面),大概了解了其用法。
先说概念
java的enum是在jdk1.5引入的,中文翻译为枚举,看意思就知道,是表示一组相同类型的常量,常用到的比如说性别、某个公用的状态列举值等,我涉及到的有充值状态、订单状态等诸如此类的枚举例子。
对这些属性用常量的好处是显而易见的,不仅可以保证单例,且比较时候可以用 ”==” 来替换 equals ,说到这里,想起一个惭愧的事情,之前看到enum用==做的比较,当时不懂,便自以为是的全部改为了取value值用equals作比较。希望以后看到我写的代码的人不要鄙视我才好。。。
语法
一.简单的enum
enum主要是用于表示常量,在jdk1.5之前,大家通常用接口常量来表示,像这样:
public interface IColor {
public static final String RED="red";
public static final String YELLOW="yellow";
public static final String GREEN="green";
}
接口的问题,之后再好好复习一下,这里不说了。
现在用enum,我们就可以写成这样:
public enum Color {
RED,YELLOW,GREEN;
}
简单,并且有效。
先用java自带的javap命令看一下,到底发生了什么
所以实际上 Enum 类型就是以 Java 类来实现的,没有什么新的特点,只不过 java 编译器帮我们做了语法的解析和编译。你看,我们的RED等参数,在反编译的文件中,是public static final型的,同时我们发现 RED的类型,是Color型的。(其中的enmu.Color中的enmu是我的文件夹的名称,写法有误,请勿效仿)。这里便引申出来了java中enum的基本语法:
1.java的enum声明定义的类型就是一个类,而且这些类都是类库中的Enum类的子类(java.lang.Enum).
2.Color枚举类就是class,而且是一个不可以被继承的final类。其枚举值(RED,YELLOW...)都是Color类型的类静态常量, 我们可以通过下面的方式来得到Color枚举类的一个实例:Color c=Color.RED; 注意:这些枚举值都是public static final的,也就是我们经常所定义的常量方式,因此枚举类中的枚举值最好全部大写。
3.如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum实例。
4.既然枚举类是class,当然在枚举类型中有构造器,方法和数据域。但是,枚举类的构造器有很大的不同。下面慢慢说。
我们先加一个构造器,加上2个参数 key,value,
public enum Color {
RED(1,"red"),YELLOW(2,"yellow"),GREEN(3,"green");
//自定义数据域
private int key;
private String value;
//private的构造函数
private Color(int key,String value){
this.key = key;
this.value = value;
}
}
注:构造器规定的用法
1.构造器只是在构造枚举值的时候被调用。
2.构造器只能私有private,绝对不允许有public构造器。 这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域可以允许外部访问
3.所有枚举类都继承了Enum的方法,java不支持多继承,enum不能再继承其他类。
二、enum中的方法
- ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。从0开始计算。
Color.RED.ordinal(); //返回结果:0
Color.YELLOW.ordinal(); //返回结果:1 - compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)
Color.RED.compareTo(Color.YELLOW); //返回结果 -1 - values()方法: 静态方法,返回一个包含全部枚举值的数组。
Color[] colors=Color.values();
for(Color c:colors){
System.out.print(c+”,”);
}//返回结果:RED,YELLOW,GREEN, - toString()方法: 返回枚举常量的名称。
Color c=Color.RED;
System.out.println(c);//返回结果: RED - valueOf()方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。
Color.valueOf(“YELLOW”); //返回结果: Color.YELLOW
- equals()方法: 比较两个枚举类对象的引用。
三、enum的常用场景
- 列举常量
- 使用switch
- 向枚举中添加新方法
- 覆盖枚举的方法
- 实现接口,不能继承其他类,但是可以实现接口。
- 使用接口组织枚举,如
public interface Food {
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
}
enum Dessert implements Food {
FRUIT, CAKE, GELATO
}
}
- 新增自定义方法
RED(1,"red"){
@Override
public boolean isStop(){
return true;
}
},YELLOW(2,"yellow"),GREEN(3,"green");
- 枚举集合的使用
// EnumSet的使用
EnumSet<Color> ColorSet = EnumSet.allOf(Color.class);
for (Color c3 : ColorSet) {
System.out.println(c3);
}
// EnumMap的使用
EnumMap<Color, String> ColorMap = new EnumMap(Color.class);
ColorMap.put(Color.RED, "红色");
ColorMap.put(Color.YELLOW, "黄色");
ColorMap.put(Color.GREEN, "绿色");
// ... ...
for (Iterator<Entry<Color, String>> iter = ColorMap.entrySet().iterator(); iter.hasNext();) {
Entry<Color, String> entry = iter.next();
System.out.println(entry.getKey().name() + ":" + entry.getValue());
}
发现,看到的和写出来的还是有很大差距的。以后定期谢谢文章,锻炼一下,顺便理顺一下思路。
最后,贴一下代码:
package enmu;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map.Entry;
public enum Color implements IColor{
RED(1,"red"){
@Override
public boolean isStop(){
return true;
}
},YELLOW(2,"yellow"),GREEN(3,"green");
//自定义数据域
private int key;
private String value;
//private的构造函数
private Color(int key,String value){
this.key = key;
this.value = value;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public boolean isStop(){
return false;
}
//新增的普通方法
public static String getValue(int key){
for(Color c2:Color.values()){
if(c2.getKey() == key){
return c2.getValue();
}
}
return null;
}
//覆盖方法
@Override
public String toString(){
return this.key+"_"+this.value;
}
@Override
public void print(){
System.out.println("实现接口方法");
}
public static void main(String[] args){
Color color = Color.RED;
System.out.println("RED.ordinal="+Color.RED.ordinal());
System.out.println("YELLOW.ordinal="+Color.YELLOW.ordinal());
System.out.println("GREEN.ordinal="+Color.GREEN.ordinal());
System.out.println("compareTo="+Color.RED.compareTo(Color.YELLOW));
System.out.println("compareTo="+Color.RED.compareTo(Color.GREEN));
System.out.println("compareTo="+Color.RED.compareTo(Color.RED));
System.out.println("compareTo="+Color.GREEN.compareTo(Color.YELLOW));
System.out.println(Color.RED==Color.GREEN);
Color[] cs = Color.values();
for(Color c : cs){
System.out.print(c+",");
System.out.println("");
}
Color c1 = Color.valueOf("YELLOW");
System.out.println("valueof=="+c1);
// EnumSet的使用
EnumSet<Color> ColorSet = EnumSet.allOf(Color.class);
for (Color c3 : ColorSet) {
System.out.println(c3);
}
// EnumMap的使用
EnumMap<Color, String> ColorMap = new EnumMap(Color.class);
ColorMap.put(Color.RED, "红色");
ColorMap.put(Color.YELLOW, "黄色");
ColorMap.put(Color.GREEN, "绿色");
// ... ...
for (Iterator<Entry<Color, String>> iter = ColorMap.entrySet().iterator(); iter.hasNext();) {
Entry<Color, String> entry = iter.next();
System.out.println(entry.getKey().name() + ":" + entry.getValue());
}
}
}
参考文章如下,排名不分先后,随手而写: