0%

java枚举

介绍

java开始是没有枚举的,可能是为了方便别的语言转向java所以在jdk1.5中推出了枚举这一特性,其本质还是一个多例模式,下面就进行仔细地讲解。

讲解

一、关键字enum

java中声明一个枚举类使用enum关键字进行申明,比较简单,直接例子:

1
2
3
enum Colour{
RED,GREEN,BLUE
}

二、类Enum

熟悉java的人都知道java里面还有一个类叫Enum,那么类Enum 和关键字enum有什么关系呢?

具体的关系为:

使用了enum定义的枚举类,其实本质上是一个class继承了Enum。也就是说其实类Enum是enum定义枚举类的父类。

下面就根据jdk文档的内容研究下Enum的相关的知识

1.类的申明

枚举1

可以看出这是个类是个抽象类,并且实现了接口Comparable<E>和Serializable,然后从泛型嵌套

< E extends Enum<E>>可以知道他的子类有泛型上限,只能是Enum或者Enum的子类。

2.相关函数

  • 构造函数
1
2
protected	Enum(String name, int ordinal)
//Sole constructor.唯一的构造函数

说明了Enum类还有两个数据成员nameordinal

  • name和ordinal函数

    1
    2
    3
    String	name()
    //Returns the name of this enum constant, exactly as declared in its enum declaration.
    //取得名字
    1
    2
    3
    int	ordinal()
    //Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero).
    //取得序号

    这两个函数方法比较简单,直接展示用法以上面的枚举类Colour为例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static void main(String[] args) {
    Colour red = Colour.RED;
    Colour green = Colour.GREEN;
    Colour blue = Colour.BLUE;
    System.out.println(red.ordinal()+"-----------"+red.name());
    System.out.println(green.ordinal()+"-----------"+green.name());
    System.out.println(blue.ordinal()+"-----------"+blue.name());

    }

    输出的结果:

    0—————-RED
    1—————-GREEN
    2—————-BLUE

  • values和valuesOf函数

1
2
static <T extends Enum<T>> T	valueOf(Class<T> enumType, String name)
//Returns the enum constant of the specified enum type with the specified name.

values其实是利用valuesOf而实现,下面展示具体用法:

values:

1
2
3
4
5
6
public static void main(String[] args) {
for (Colour temp : Colour.values()) {
System.out.println(temp.ordinal()+"-----------"+temp.name());
}

}

结果和上面一样,就不展示了。

valuesOf

1
2
3
4
5

public static void main(String[] args) {
Colour red = Colour.valueOf("RED");
System.out.println(red.ordinal()+"-----------"+red.name());
}

结果:

0—————-RED

三、枚举类中定义其他结构

java中的枚举既然是一个类,那么在里面还可以定义其他结构,相比于其他语言来说Java的枚举类还是比较灵活。

但是还是有一些需要注意的点:

  • 构造函数只能是private

    因为枚举的实现其实是多例模式,在多例当中为了防止在类的外部就可以通过构造器来新建实例,所以将构造函数设置成private类型。

  • 枚举类中的例子只能在第一行

    这就是个规定,记住就行。

  • 枚举类可以继承接口

  • 枚举可以配合switch一起使用
    需要注意case上的一些细节,可以参考下面的例子。

具体举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//定义接口
interface IColour{
public void print();
}

enum Colour implements IColour {
RED("红色"),GREEN("绿色"),BLUE("蓝色");//这个只能写在第一行

private String title;
//构造函数只能私有
private Colour(String title) {
this.title = title;
}


@Override
public void print() {
// TODO Auto-generated method stub
System.out.println(this.title);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
Colour colour = Colour.RED;
switch (colour) {
case RED: //不能使用Colour.RED,否则会报错
System.out.println("我是红色");
break;
case GREEN:
System.out.println("我是绿色");
break;
case BLUE:
System.out.println("我是蓝色");
break;
default:
break;
}

}

除此之外枚举还可以摆脱之前使用的if语句和switch语句,也可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class Pizza {

private PizzaStatus status;
public enum PizzaStatus {
ORDERED (5){
@Override
public boolean isOrdered() {
return true;
}
},
READY (2){
@Override
public boolean isReady() {
return true;
}
},
DELIVERED (0){
@Override
public boolean isDelivered() {
return true;
}
};

private int timeToDelivery;

public boolean isOrdered() {return false;}

public boolean isReady() {return false;}

public boolean isDelivered(){return false;}

public int getTimeToDelivery() {
return timeToDelivery;
}

PizzaStatus (int timeToDelivery) {
this.timeToDelivery = timeToDelivery;
}
}

public boolean isDeliverable() {
return this.status.isReady();
}

public void printTimeToDeliver() {
System.out.println("Time to delivery is " +
this.getStatus().getTimeToDelivery());
}

// Methods that set and get the status variable.
public void setStatus(PizzaStatus status) {
this.status = status;
}

public PizzaStatus getStatus() {
return status;
}



public static void main(String[] args) {
Pizza testPz = new Pizza();
testPz.setStatus(Pizza.PizzaStatus.READY);
System.out.println(testPz.isDeliverable());
}
}

总结

枚举内容比较基础,需要熟悉一下。