Java枚举

Java在1.5之后,有了enum关键字,定义枚举类。它是一种特殊的类,同样可以有方法和属性,可以实现一个或多个接口,可以定义构造器。它与普通类区别:

1.枚举类可实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是Object类。而java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。

2.枚举类的构造器只能使用private访问控制符,省略则默认为private,指定也只能指定private。

3.枚举类的所有实例必须在枚举类中显式列出。系统自动添加public static final修饰符。

4.所有枚举类都提供了一个values方法,方便遍历所有的枚举值。

使用enum关键字创建EnumSeason,如下:

 

1 enum EnumSeason  {
2    SPRING, SUMMER, FALL, WINTER
3}

替代使用String定义常量:

 

1 public class EnumSeason  {
2    public static final String SPRING = “SPRING”;
3    public static final String SUMMER = “SUMMER”;
4    public static final String FALL = “FALL”;
5    public static final String WINTER = “WINTER”;
6}

由于使用字符串常量这种方式是编译时常量,即在.java文件在编译成.class时,会把这些常量替换为相应的值。这样其他的类里有引用到的时候也会被替换,如果字符串常量发生改变了,那么其他的类也要重新进行编译。而枚举是运行时,枚举类改变后,只需要重新编译枚举类即可。

使用枚举类:

 

01 public static void main(String[] args) {
02     judge(EnumSeason.SPRING);
03     for (EnumSeason s : EnumSeason.values()) {
04         System.out.println(s.ordinal() + ":" + s);
05     }
06}
07 public static void judge(EnumSeason season) {
08     switch (season) {
09         case SPRING:
10             System.out.println("春暖花开");
11             break;
12         case SUMMER:
13             System.out.println("夏日温情");
14             break;
15         case FALL:
16             System.out.println("秋高气爽");
17             break;
18         case WINTER:
19             System.out.println("东风瑟瑟");
20         default:
21             System.out.println("什么呀这是");
22     }
23}

 

运行结果如下:

春暖花开

0:SPRING

1:SUMMER

2:FALL

3:WINTER

为枚举类添加属性,如下:

 

1 enum Gender {
2     MALE, FEMALE;
3     public String name;
4}

 

使用如下:

 

1 Gender g = Enum.valueOf(Gender.class"FEMALE");
2 g.name = "女";
3 System.out.println(g + "代表:" + g.name);

 

Enum类的静态方法valueOf(Class,  String)

上面直接访问enum属性的方式不太安全,可以改为添加setter/getter方法:

 

01 enum Gender {
02     MALE, FEMALE;
03     private String name;
04 
05     public String getName() {
06         return name;
07     }
08 
09     public void setName(String name) {
10         switch(this) {
11         case MALE:
12             if("男".equals(name)){
13                 this.name = name;
14             else {
15                 System.out.println("参数错误");
16                 return;
17             }
18             break;
19         case FEMALE:
20             if("女".equals(name)){
21                 this.name = name;
22             else {
23                 System.out.println("参数错误");
24                 return;
25             }
26             break;
27         }
28     }
29}

 

主函数如下:

 

1 Gender g = Enum.valueOf(Gender.class"FEMALE");
2 g.setName("女");
3 System.out.println(g + "代表:" + g.getName());
4 
5 g.setName("男"); //参数错误
6 System.out.println(g + "代表:" + g.getName());

 

这种方法仍不够科学,因为枚举类通常设计成不可变类,即属性值不允许修改,这样更安全,因此应该把枚举类的属性都使用private final修饰。可使用private构造函数方式,如下:

 

1 enum Gender {
2     MALE("男"), FEMALE;
3     private final String name;
4      
5     private Gender(String name) {
6         this.name = name;
7     }
8}

 

Enum枚举实现接口,例子如下:因为有了构造函数,因此枚举变量中每个值都得使用构造函数方式,因此MALE("男")没有问题,而FEMALE就编译通不过,因为没有无参的构造函数。

 

01 interface InterfaceForEnum {
02     public void fun();
03}
04 
05 enum EmotionEnum implements InterfaceForEnum{
06     HAPPY, ANGRY;
07 
08     @Override
09     public void fun() {
10         System.out.println("I'm an emotion");
11     }
12}

 

这种方式,每个枚举值调用fun()方法时,行为就一样了,没能达到接口效果,可改为如下:

 

01 enum EmotionEnum implements InterfaceForEnum{
02     HAPPY {
03         public void fun() {
04             System.out.println("I'm very happy");
05         }
06     }
07     , ANGRY {
08 
09         @Override
10         public void fun() {
11             System.out.println("I'm angry");
12         }
13     }
14}

同样,也可以在enum中定义抽象方法,这样每个枚举值都得实现该抽象方法。

01 enum EmotionEnum {
02     HAPPY {
03         public int evel(int n1, int n2) {
04             return n1 - n2;
05         }
06     }
07     , ANGRY {
08          
09         public int evel(int n1, int n2) {
10             return n1 + n2;
11         }
12     };
13      
14     public abstract int evel(int n1, int n2);
15}

 

同时,使用枚举实现单例模式,可以实现单例模式,并且可以防止通过反射和序列化方式破解单例

 

1 public enum Singleton {
2     INSTANCE;
3 
4     public void method1() {
5         System.out.println("hello");
6     }
7}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值