概述
枚举是一个被命名的整型常数的集合,用于声明一组常量。在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代。
JDK 1.5 之前:
class Season {
public static final String SPRING = "春天";
public static final String SUMMER = "夏天";
public static final String AUTUMN = "秋天";
public static final String WINTER = "冬天";
}
public class TestSeason {
public static void main(String[] args){
System.out.println(Season.SPRING);
}
}
输出:
春天
enum关键字定义枚举类:
enum Season{
SPRING,SUMMER,AUTUMN,WINTER;
}
public class TestSeason {
public static void main(String[] args){
Season season = Season.SPRING;
System.out.println(season);
}
}
输出:
SPRING
与switch结合使用,可以直接判断枚举类型。
public class TestSeason {
public static void main(String[] args){
Season season = Season.SPRING;
switch(season) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}
枚举类特点
- 类的对象只有有限个,确定的。当需要定义一组常量时,强烈建议使用枚举类。
- 如果枚举类中只有一个对象,则可以作为单例模式的实现方式。
- 任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。
- 最后一个枚举成员使用分号结束。
枚举类内置的方法
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。所有枚举实例都可以调用 Enum 类的方法
- values():以数组形式返回枚举类型的所有成员。
- valueOf():将普通字符串转换为枚举实例。
- compareTo():比较两个枚举成员在定义时的顺序差。
- ordinal():获取枚举成员的索引位置,从0开始分配了编号。
public class TestEnum {
public static void main(String[] args){
/* values()方法 */
Season[] values = Season.values();
for (Season season : values){
System.out.println(season);
}
/* valueOf方法 */
Season season = Season.valueOf("AUTUMN");
System.out.println(season);
/* ordinal方法 */
int ordinal = season.ordinal();
System.out.println("ordinal=" + ordinal);
/* ordinal方法 */
int i = Season.valueOf("WINTER").compareTo(Season.valueOf("AUTUMN"));
System.out.println("i=" + i);
}
}
输出:
SPRING
SUMMER
AUTUMN
WINTER
AUTUMN
ordinal=2
i=1
自定义枚举方法
Java 为枚举类型提供了一些内置的方法,枚举常量也可以自定义方法。此时要注意必须在枚举实例的最后一个成员后添加分号,而且必须先定义枚举实例。
enum Season{
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","白雪皑皑");
//声明Season对象的属性priavte final修饰
private final String seasonName;
private final String seasonDesc;
//私有化的构造器,并给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//获取属性方法 public
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}';
}
}
注:SPRING(“春天”,“春暖花开”) 等 枚举实例的定义必须放在最前面。
调用:
public class TestEnum {
public static void main(String[] args){
Season season = Season.SPRING;
System.out.println("seasonName=" + season.getSeasonName());
System.out.println("seasonDesc=" + season.getSeasonDesc());
}
}
输出:
seasonName=春天
seasonDesc=春暖花开
实现接口的枚举类
定义接口Info
public interface Info {
void show();
}
enum类中实现抽象方法
enum Season implements Info{
SPRING("春天","春暖花开"),
SUMMER("夏天","夏日炎炎"),
AUTUMN("秋天","秋高气爽"),
WINTER("冬天","白雪皑皑");
//声明Season对象的属性priavte final修饰
private final String seasonName;
private final String seasonDesc;
//私有化的构造器,并给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//获取属性方法 public
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}';
}
@Override
public void show(){
System.out.println("这是一个季节");
}
}
调用:
public class TestEnum {
public static void main(String[] args){
Season season = Season.SPRING;
season.show();
}
}
输出:
这是一个季节
枚举类的对象分别实现接口中的抽象方法
enum Season implements Info{
SPRING("春天","春暖花开") {
@Override
public void show() {
System.out.println("春天来了,小燕子忙着飞舞");
}
},
SUMMER("夏天","夏日炎炎") {
@Override
public void show() {
System.out.println("夏天来了,青蛙呱呱叫");
}
},
AUTUMN("秋天","秋高气爽") {
@Override
public void show() {
System.out.println("秋天来了,果实挂满了枝头");
}
},
WINTER("冬天","白雪皑皑") {
@Override
public void show() {
System.out.println("冬天来了,大雪皑皑");
}
};
//声明Season对象的属性priavte final修饰
private final String seasonName;
private final String seasonDesc;
//私有化的构造器,并给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//获取属性方法 public
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}';
}
}
调用:
public class TestEnum {
public static void main(String[] args){
Season season = Season.SPRING;
season.show();
}
}
输出:
春天来了,小燕子忙着飞舞
EnumMap 与 EnumSet
为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 与 EnumSet。使用它们可以更高效地操作枚举类型。
EnumMap 类
EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。
下面是使用 EnumMap 的一个代码示例。枚举类型 DataBaseType 里存放了现在支持的所有数据库类型。针对不同的数据库,一些数据库相关的方法需要返回不一样的值,例如示例中 getURL() 方法。
// 定义数据库类型枚举
public enum DataBaseType {
MYSQUORACLE,DB2,SQLSERVER
}
// 某类中定义的获取数据库URL的方法以及EnumMap的声明
private EnumMap<DataBaseType,String>urls = new EnumMap<DataBaseType,String>(DataBaseType.class);
public DataBaseInfo() {
urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample");
urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb");
urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample");
urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://sql:1433;Database=mydb");
}
//根据不同的数据库类型,返回对应的URL
// @param type DataBaseType 枚举类新实例
// @return
public String getURL(DataBaseType type) {
return this.urls.get(type);
}