• java之类型安全的枚举


    why

      枚举,顾名思义,就是一组可罗列的值,如四季春夏秋冬,方位东南西北,星期,月份等。在J2SE5.0 Tiger会出现之前,通常定义一个普通类或者抽象类,在类中定义一组public staic final 修饰的成员变量来表示这样的数据。

    public abstract class Direction {
        public static final int EAST = 0;  //
        public static final int WEST = 1;  //西
        public static final int SOUTH = 2;  //
        public static final int NORTH = 3;  //
    }

    然后我们就能通过“类名.变量名“Direction.EAST的形式来使用这些常量。

      那么像这样定义有什么不好的地方呢?我就举个例子来说明,比如有一个方法,需要接收上述的参数,那方法的声明肯定就像这样 returnType methodName(int direction); 注意方法的参数是int型,即任何的int类型的值不限0、1、2、3都能够作为该方法的参数。为了避免意料之外的结果,必须限定参数的上限和下限,否则就容易误传入非正确的int值,编译器是检查不出这类错误的,全靠人为控制。另一方面,使用静态常量时候,常常不够直观,不看定义,谁也不知道0、1、2、3究竟表示什么,而且当有要罗列多少种方向的需求的时候,也不方便。

      J2SE5.0提供了解决上述问题的一种方式,即用关键字enum定义的枚举。它克服了静态常量表示法的不足,在编译的时候,编译器就能检查出非法的参数,并不需要设定程序的上下界,所以说枚举是类型安全的。而且通过它自带的方法,很容易罗列所表示的值,简单明了。

    what

      那么枚举如何表示上述的方向呢?

    public enum Direction{
        EAST,WEST,SOUTH,NORTH;
    }

      上面代码就是java枚举的定义。枚举本质上还是一个类,是和class,interface,annotation是一个级别的,源文件编译之后还是一个字节码文件,表面上我们用关键字enum定义,看不出什么,实际上编译器帮我们完成了大部分的东西。可以通过反编译工具把字节码文件反编译过来,就能看到编译器做了什么事。

      所有枚举类型都继承自Enum,Enum是所有枚举类型的基类。这个继承是编译器帮我们完成的。 因为枚举已经继承了Enum,所以不能再继承别的类,可以实现接口。枚举的构造函数只能是private或者默认修饰符,所以在编译完成,究竟有哪些枚举实例已经固定了。

    how

    带构造函数的枚举,这个例子也说明枚举可以添加成员变量和方法

    public enum Direction {
        EAST("东"), WEST("西"), SOUTH("南"), NORTH("北");
    
        private final String name;
    
        private Direction(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }

    实现接口的枚举

    public enum Direction implements MyService {
        EAST, WEST, SOUTH, NORTH;
    
        public void doSomething() {
            System.out.println(this.name());
        }
    }
    
    interface MyService {
        public void doSomething();
    }

    枚举(重写父类方法)

    public enum Direction {
        EAST {
            public void doSomething() {
                System.out.println("东");
            }
        },
        WEST {
            public void doSomething() {
                System.out.println("西");
            }
        },
        SOUTH {
            public void doSomething() {
                System.out.println("南");
            }
        },
        NORTH;
    
        public void doSomething() {
            System.out.println(this.name());
        }
    }

    枚举(实现抽象方法)

    public enum Direction {
        EAST {
            @Override
            void doSomething() {
                System.out.println("east");
            }
        },
        WEST {
            @Override
            void doSomething() {
                System.out.println("west");
            }
    
        },
        SOUTH {
            @Override
            void doSomething() {
                System.out.println("south");
            }
        },
        NORTH {
            @Override
            void doSomething() {
                System.out.println("north");
            }
        };
    
        abstract void doSomething();
    }

      枚举比较

    Direction direction = Direction.EAST;
    System.out.println(direction.compareTo(Direction.WEST));
    
    // if语句中的使用
    if (Direction.EAST == direction) {
        System.out.println("equal");
    } else
        System.out.println("not equal");
    
    // 可以用于switch语句
     switch (direction) {
        case WEST:
           System.out.println("west");
           break;
        case EAST:
            System.out.println("east");
            break;
        case SOUTH:
            System.out.println("south");
            break;
        case NORTH:
            System.out.println("north");
            break;
        default:
            System.out.println("default");
     }

      至于枚举类从父类继承来的方法,请自行查阅java api帮助文档。枚举的出现,也在java集合框架中添加了两个成员,EnumSet和EnumMap,即枚举集合和枚举映射。EnumSet是一个抽象类,里面定义了创建枚举集合的不同静态方法,具体的用法看api,与普通的set和map无异。

      如果想了解更多的内容,请看这篇文章http://www.iteye.com/topic/678381

  • 相关阅读:
    Easy File Sharing Web Server 7.2
    我的安全之路——二进制与逆向篇
    下拉滚动,导航条悬停在顶部
    Java-json对象转Map
    Java-验证码生成(数字+字母)
    Java-List分页工具
    HDU-1556-Color the ball (线段树和差分数组两种解法)
    牛客练习赛34-C-little w and Segment Coverage(差分数组)
    牛客练习赛34-C-little w and Segment Coverage(差分数组)
    差分数组原理及应用
  • 原文地址:https://www.cnblogs.com/liuyonglong/p/3561581.html
Copyright © 2020-2023  润新知