----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有4个对象;再比如行星类,它只有9个对象。这种实例有限而且固定的类,在Java里被称为枚举类。
手动实现枚举类
如果需要手动实现枚举类,可以采用如下设计方式
通过private将构造函数隐藏起来
把这个类的所有可能实例都通过public static final修饰的类变量来保存
如果有必要,可以提供一些静态方法,允许其他程序根据特定参数来获取与之匹配的实例
下面程序将定义一个Season类,这个类只能产生4个对象,该Season类被定义成一个枚举类。
public class Season
{
//把Season类定义成不可变的,将其Field也定义成final
private final String name;
private final String desc;
public static finalSeason SPRING
= new Season("春天" , "趁春踏青");
public static finalSeason SUMMER
= new Season("夏天" , "夏日炎炎");
public static finalSeason FALL
= new Season("秋天" , "秋高气爽");
public static finalSeason 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类中包含了4个static final常量Field,这4个常量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=4;
这种定义方法简单明了,但存在如下几个问题
类型不安全:因为上面的每个季节实际上是一个int整数,因此完全可以把一个季节当成一个整数使用,例如进行加法运算SEASON_SPRING+SEASON_SUMMER,这样的代码完全正常。
没有命名空间:当需要使用季节时,必须在SPRING前使用SEASON_前缀,否则程序可能与其他类中的静态常量混淆
打印输出的意义不明确:当我们打印输出某个季节时,例如打印SEASON_SPRING,实际上输出的是1,这个1很难猜测它代表了春天。
从这个意义上来看,枚举类的存在确实很有意义,但手动定义枚举类的代码量比较大,实现起来也比较麻烦,所以Java从JDK1.5后就增加了对枚举类的支持。