枚举使用

定义

1
2
3
4
5
public enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
// 枚举类对象不能通过 new 出来,引用的时候直接类.实例名
Week w = Week.MONDAY;

构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public enum Week {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

Week(){
System.out.println("hello");
}

}

public class Test {
public static void main(String[] args) {
Week w = Week.FRIDAY;
}
}

//hello hello hello hello hello hello hello
//构造函数共执行了 7 次,正好对应类中枚举项的数量。
//其实此类的枚举项的创建,就相当于其他类调用无参构造器 new 出来的对象。

除了无参构造器,枚举类也有有参构造器。

1
2
3
4
5
6
7
8
9
public enum Week {
SUNDAY(7), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6);

Week(int weekNum){
System.out.println(weekNum);
}

}
//7 1 2 3 4 5 6

枚举类成员

枚举类和正常类一样,也可以有成员变量、实例方法、静态方法等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public enum Week {
SUNDAY(7), MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4), FRIDAY(5), SATURDAY(6);

private int weekNum;

Week(int weekNum){
this.weekNum = weekNum;
}

public int getWeekNum() {
return weekNum;
}

}
public class Test {
public static void main(String[] args) {
Week w = Week.FRIDAY;
System.out.println(w.getWeekNum());
}
}

//5

枚举类中还可以有抽象方法。

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
public enum Week {
SUNDAY(){
@Override
public void getWeekNum() {
System.out.println(7);
}
},
MONDAY() {
@Override
public void getWeekNum() {
System.out.println("星期一");
}
},

TUESDAY(){
@Override
public void getWeekNum() {
System.out.println("礼拜二");
}
},
WEDNESDAY(){
@Override
public void getWeekNum() {
System.out.println("周三");
}
};

public abstract void getWeekNum();
}

public class Test {
public static void main(String[] args) {
Week w = Week.TUESDAY;
w.getWeekNum();
}
}

//礼拜二

每个枚举类都有两个 static 方法:

  • static Direction[] values():返回本类所有枚举常量;

  • static Direction valueOf(String name):通过枚举常量的名字返回Direction常量,注意,这个方法与Enum类中的valueOf()方法的参数个数不同。

1
2
3
4
5
6
7
8
9
10
11
public class Test {
public static void main(String[] args) {
for (Week w : Week.values()) {
System.out.println(w);
}
System.out.println("星期天:" + Week.valueOf("SUNDAY"));
}
}

//SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY
//星期天:SUNDAY

使用场景

类型约束

需要传入商品折扣计算价格,使用常量定义没有类型上的约束,传入任何 double 类型的值都可以。

1
2
3
4
5
6
7
8
9
10
public class Discount {
public static final double EIGHT_DISCOUNT = 0.8;

public static final double SIX_DISCOUNT = 0.6;

public static final double FIVE_DISCOUNT = 0.5;
}
BigDecimal calculatePrice(double discount){
//...
}

如果你使用枚举来定义这种情况,就会有更强的类型约束:

1
2
3
4
5
6
7
8
9
10
11
12
13
public enum Discount {
EIGHT_DISCOUNT(0.8), SIX_DISCOUNT(0.6), FIVE_DISCOUNT(0.5);

private double discountNum;

Discount(double discountNum) {
this.discountNum = discountNum;
}

double getDiscountNum(){
return discountNum;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
calculatePrice(Discount.EIGHT_DISCOUNT);
}

static BigDecimal calculatePrice(Discount discount){
System.out.println(discount.getDiscountNum());
//...
return null;
}
}

//0.8

switch中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
Week w = Week.MONDAY;
switch (w) {
case MONDAY:
System.out.println("周一"); break;
case TUESDAY:
System.out.println("周二"); break;
}
}
}

//周一

消除if/else

1
2
3
4
public interface Eat {
//吃
String eat();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public enum AnimalEnum implements Eat {
Dog(){
@Override
public void eat() {
System.out.println("吃骨头");
}
},

Cat() {
@Override
public void eat() {
System.out.println("吃鱼干");
}
},

Sheep() {
@Override
public void eat() {
System.out.println("吃草");
}
}
}
1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
AnimalEnum.valueOf("Cat").eat();
}
}

//吃鱼干

单例模式

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
/**
* @Description: 枚举 线程安全
*/
public class SingletonExample {

/**
* 构造函数私有化,避免外部创建实例
*/
private SingletonExample(){}

private static SingletonExample getInstance() {
return Singleton.INSTANCE.getInstance();
}

private enum Singleton {
INSTANCE;
private SingletonExample instance;

// JVM 保证这个方法绝对只调用一次
Singleton() {
instance = new SingletonExample();
}

public SingletonExample getInstance() {
return instance;
}
}
}
0%