但行好事  莫问前程

枚举系列(一):手动实现枚举类

在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有四个对象;再比如行星类,目前只有9个对象。这种实例有限而且固定的类,在Java里被称为枚举类。如果需要手动实现枚举类,可以采用如下方式:

(1).通过private把构造器隐藏起来。

(2).把这个类的所有可能实例都使用public static final修饰的类变量来保存。

(3).如果有必要,可以提供一些静态方法,允许其他程序根据特定参数来获取与之匹配的示例。

下面程序定义一个Season类,这个类只能产生四个对象,该Season类被定义成一个枚举类。

public class Season
{
    //把Season类定义成不可变的,将其Field也定义成final
    private final String name;
    private final String desc;
    public static final Season SPRING 
        = new Season("春天" , "趁春踏青");
    public static final Season SUMMER
        = new Season("夏天" , "夏日炎炎");
    public static final Season FALL 
        = new Season("秋天" , "秋高气爽");
    public static final Season WINTER
        = new Season("冬天" , "围炉赏雪");
    public static Season getSeason(int seasonNum)
    {
    switch(seasonNum)
    {
        case 1 :
            return SPRING;
        case 2 :
            return SUMMER;
        case 3 :
            return FALL;
        case 4 :
            return WINTER;
        default :
            return null;
        }
    }
    //将构造器定义成private访问权限
    private Season(String name , String desc)
    {
        this.name = name;
        this.desc = desc;
    }
    //只为name和desc提供getter方法
    public String getName()
    {
        return this.name;
    }

    public String getDesc() {
        return this.desc;
    }
}

上面的Season类是一个不可变类,在上面的Season类中包含了4static final常量的Field,这四个常量Field就代表了该类所能创建的对象。当其他程序需要使用Season对象时,即可通过如Season.SPRING的方式来取得Season对象,也可通过getSeason静态工程方法来获取Season对象。

下面程序演示了如何使用Season类。

public class SeasonTest {
    public SeasonTest(Season s) {
        System.out.println(s.getName() + ",这真是一个" + s.getDesc() + "的季节");
    }

    public static void main(String[] args) {
        // 直接使用Season的FALL常量代表一个Season对象
        new SeasonTest(Season.FALL);
    }
}

从上面程序中不难看出,使用枚举类可以使程序更加健壮,避免创建对象的随意性。有的程序员喜欢使用简单的静态常量来表示这种情况。

    public static final int SEASON_SPRING = 1;
    public static final int SEASON_SUMMER = 2;
    public static final int SEASON_FALL = 3;
    public static final int SEASON_WINTER = 14;

这种定义方式简单明了,但存在如下几个问题:

(1).类型不安全:因为上面的每个季节实际上是一个int整数,因此完全可以把一个季节当成一个int整数使用,例如进行加法运算SEASON_SPRING+SEASON_SUMMER,这样的代码完全正常。

(2).没有命名空间:当需要使用季节时,必须在SPRING前使用SEASON_前缀,否则程序可能与其他类中的静态常量混淆。

(3).打印输出的意义不明确:当我们打印输出某个季节时,例如打印SEASON_SPRING,实际上输出的是1,这个1很难猜测它代表了春天。

从这个意义上面来看,枚举类的存在的确很有意义,但是手动定义枚举类的代码量比较大,实现起来也比较麻烦,所以JavaJDK1.5后就增加了对枚举类的支持。

附:源代码示例

github地址:点击查看
码云地址:点击查看

打赏
欢迎关注人生设计师的微信公众账号
公众号ID:longjiazuoA

未经允许不得转载:人生设计师 » 枚举系列(一):手动实现枚举类

分享到:更多 ()

人生设计师-接受不同的声音

联系我关于我