Java-枚举

本文详细介绍了Java中的枚举类型,包括概念、封装等级的不同方法、枚举类的语法、添加和重写方法、switch语句支持以及常用方法的应用。通过实例展示了如何使用枚举提高代码的可读性和健壮性。
摘要由CSDN通过智能技术生成

枚举类型

一、概念

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.

枚举类型是一种特殊数据类型,能够为一个变量定义一组预定义的常量。变量必须等于为其预定义的值之一。

枚举类中声明的每一个枚举值代表枚举类的一个实例对象。

Java中的枚举是一种特殊的数据类型,用于表示一组相关的常量,这些常量具有固定的值和名称。枚举常量通常用于表示一些固定的不可变的选项,例如颜色、方向、星期几、操作状态等。

Java枚举类型可以让我们在代码中使用更加清晰、可读的名称来表示某些常量,从而提高代码的可读性、可维护性和可重用性

二、枚举的演变

1、数据合法性验证–正则

第一:封装学生

public class Student {
	//姓名
	private String name ;
	//等级:必须只能是 A B C D E 五种级别
	private String grade ;	//ABCDE
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getGrade() {
		return grade;
	}
	public void setGrade(String grade) {
		if(!grade.matches("[ABCDE]")) {
			throw new RuntimeException("等级只能是A B C D E") ;
		}
		this.grade = grade;
	}
	
	@Override
	public String toString() {
		return "姓名:"+this.name + ",等级:"+this.grade;
	}
}

第二:测试

public class MainTest {
	public static void main(String[] args) {
		Student stu = new Student() ;
		stu.setName("张三");
		stu.setGrade("G");
		System.out.println(stu);
	}
}
2、改进,对象实现

把等级封装为一个类

第一:封装等级

public class Grade {
	private String value ;
	// 私有化构造方法,不允许在类外实例化对象
	private Grade() {}
	private Grade(String value) {
		this.value = value ;
	}
	// 实现化五个对象
	public static final Grade A = new Grade("优秀");
	public static final Grade B = new Grade("良好");
	public static final Grade C = new Grade("中等");
	public static final Grade D = new Grade("合格");
	public static final Grade E = new Grade("不合格");
	
	@Override
	public String toString() {
		return this.value;
	}
}

第二:重新封装学生对象,引用Grade对象

public class Student {
	// 姓名
	private String name ;
	// 等级:必须只能是 A B C D E 五种级别
	private Grade grade ;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Grade getGrade() {
		return grade;
	}

	public void setGrade(Grade grade) {
		this.grade = grade;
	}

	@Override
	public String toString() {
		return "姓名:"+this.name + ",等级:"+this.grade;
	}
	
}

第三:测试

public class MainTest {
	public static void main(String[] args) {
		Student stu = new Student() ;
		stu.setName("张三");
		stu.setGrade(Grade.B);
		System.out.println(stu);
	}
}
3、改进,枚举实现

把等级封装为一个枚举类,JDK5新增enum关键字,用于定义一个枚举类,枚举类也可以有构造方法(私有)、字段和方法。

第一:定义枚举类

1)简单定义

// 定义Grade枚举
enum Grade {
  // 枚举值:各枚举值表示枚举的实例对象(默认是静态的)
  A,B,C,D,E;	
}

说明:此处的Grade枚举与上面的Grade类功能一样,枚举值A,B,C,D,E就是此枚举的实例对象(而且是静态的),也就是说:枚举类中声明的每一个枚举值代表枚举类的一个实例对象。

2)改进Grade枚举—指定A、B、C、D、E五个等级对应的中文表示

public enum Grade {
	// 定义枚举列表值,同时使用构造方法初始化属性
	A("优秀"),B("良好"),C("中等"),D("合格"),E("不合格");
  
	// 定义属性:表示等级ABCDE对应的中文表示
	private String value ;
  
	// 定义构造方法
	private Grade(String value) {
		this.value = value ;
	}
  
	// 重写 toString 方法
	@Override
	public String toString() {
		return this.value;
	}
}

3)改进Grade枚举—指定A、B、C、D、E五个等级的分数范围

public enum Grade {
	/**
	 * 创建枚举列表值,并且使用构造方法初始化属性;
	 * 同时,由于枚举类中定义了抽象方法,不能直接创建枚举值,
	 * 因此,创建枚举值时,必须以匿名内部类方式创建
	 * 而且在匿名内部类中重写方法,实现返回该等级对应的分数范围
	 */
	A("优秀"){
		@Override
		public String getScoreRange() {
			return "分数>=90 && 分数<=100";
		}
	},B("良好"){
		@Override
		public String getScoreRange() {
			return "分数>=80 && 分数<90";
		}
	},C("中等"){
		@Override
		public String getScoreRange() {
			return "分数>=70 && 分数<80";
		}
	},D("合格"){
		@Override
		public String getScoreRange() {
			return "分数>=60 && 分数<70";
		}
	},E("不合格"){
		@Override
		public String getScoreRange() {
			return "分数>=0 && 分数<60";
		}
	};
  
	// 定义属性:表示等级ABCDE对应的中文表示
	private String value ;
  
	/**
	 * 构造方法
	 * @param value
	 */
	private Grade(String value) {
		this.value = value ;
	}
	
	/**
	 * 定义抽象方法
	 * @return 返回不同等级对应的分数范围
	 */
	public abstract String getScoreRange() ;
	
	// 重写 toString()方法,输出等级的中文表示
	@Override
	public String toString() {
		return this.value;
	}
  
  /**
   * 定义成员方法
   */
  public void sayHello() {
    System.out.println("成员方法");
  }

  /**
   * 定义静态方法
   */
  public static void testStatic() {
    System.out.println("静态方法");
  }
}

以下是使用抽象类来实现和以上枚举类同样的功能

public abstract class Grade {
	//定义属性:表示等级ABCDE对应的中文表示
	private String value ;
	/**
	 * 构造方法:设置各等级的中文表示
	 * @param value
	 */
	private Grade(String value) {
		this.value = value ;
	}
	
	//创建抽象类实现对象,通过匿名类实现抽象类,并实现方法
	public static Grade A = new Grade("优秀") {
		@Override
		public String getScoreRange() {
			return "分数>=90 && 分数<=100";
		}
	};
	
	public static Grade B = new Grade("良好") {
		@Override
		public String getScoreRange() {
			return "分数>=80 && 分数<90";
		}
	};
	
	public static Grade C = new Grade("中等") {
		@Override
		public String getScoreRange() {
			return "分数>=70 && 分数<80";
		}
	};
	
	public static Grade D = new Grade("合格") {
		@Override
		public String getScoreRange() {
			return "分数>=60 && 分数<70";
		}
	};
	
	public static Grade E = new Grade("不合格") {
		@Override
		public String getScoreRange() {
			return "分数>=0 && 分数<60";
		}
	};
	
	/**
	 * 抽象方法
	 * @return 返回不同等级对应的分数范围
	 */
	public abstract String getScoreRange() ;
	
	//重写toString()方法,输出等级的中文表示
	@Override
	public String toString() {
		return this.value;
	}
}

第二:封装学生对象,引用Grade枚举

与上例中的Student类一样,不需要做任何改动。验证了Grade枚举类与上例的Grade类功能一样。

第三:测试

public class MainTest {
	public static void main(String[] args) {
		// 创建学生对象并初始化数据
		Student stu = new Student() ;
		stu.setName("张三");
		stu.setGrade(Grade.B);
		
		// 输出学生信息
		System.out.println(stu);
		
		// 获取学生的等级,并打印输出该等级的分数范围
		Grade g = stu.getGrade();
		System.out.println("分数范围:" + g.getScoreRange());
    
    // 调用枚举成员方法
    g.sayHello();

    // 调用枚举静态方法
    Grade.testStatic(); 
	}
}

三、语法

[访问修饰符] enum 枚举类名 {
  // 枚举常量 - 枚举实例(枚举值)
  
  // 成员变量、常量
  // 成员方法、抽象方法、静态方法、重载方法、重写方法
  // 构造方法
}

要点:

1)枚举是特殊的类(常量类),在声明枚举类时,可以定义成员变量、方法和构造方法

  • 枚举常量是枚举类型的实例,它们是不可变的、公共的、静态的和最终的。
  • 构造方法必须私有的。

2)枚举实例必须要求先定义,也就说,枚举值必须定义在枚举类的第一行代码中;

3)规范

  • 命名规范:全大写命名,多个单词间使用下划线分隔
  • 注释规范:所有的枚举类型字段必须要有注释,说明每个数据项的用途

4)各个枚举值逗号分隔,枚举类中仅仅只有枚举值,则可以省略分号,否则必须显式写分号

5)不能泛型化

// 错误
public enum Color<T> {
    ...
}

说明:Java 枚举类型并不支持泛型。这是因为枚举类型是在编译时确定的,而泛型是在运行时确定的。

6)使用枚举常量

语法:枚举类名.枚举常量

7)枚举API方法

四、要点

1、添加新的方法
public enum Color {
	RED("红"),GREEN("绿"),BLUE("蓝");
	private String value ;
	private Color(String value) {
		this.value = value ;
	}
  // 添加成员方法
	public String getValue() {
		return value;
	}
}
2、重写方法
public enum Color {
	RED("红"),GREEN("绿"),BLUE("蓝");
	private String value ;
	private Color(String value) {
		this.value = value ;
	}
	// 添加成员方法
	public String getValue() {
		return value;
	}
  // 重写方法
	public String toString() {
		return this.value;
	}
}
3、switch的支持

JDK5中扩展了switch语句,它除了可以接收int,byte,char,short外,还可以接收一个枚举类型。

//1)定义枚举
public enum Color {
    RED,GREEN,BLUE
}

//2)测试 -- switch对枚举的支持
public class MainTest {
	public static void main(String[] args) {
		Color week = Color.RED;
		
		switch(week) {
		case RED:
			System.out.println("红");break;
		case GREEN:
			System.out.println("绿");break;
		case BLUE:
			System.out.println("蓝");break;
		}
	}
}
4、Enum常用方法

枚举类型都隐式继承了java.lang.Enum类,因此不能继承其他类,但可以实现接口。

Java中声明的枚举类,均是java.lang.Enum类的子类,它继承了Enum类的所有方法。

public enum Color {
    RED("红"),GREEN("绿"),BLUE("蓝");
    private String value ;
    private Color(String value) {
      this.value = value ;
    }
    public String getValue() {
      return value;
    }
}
1)name()

返回枚举常量的名称,正是因为在其枚举声明中声明。

Color color = Color.RED;
String name = color.name();
System.out.println(name);							// 输出:RED
2)valueOf(String name)

根据枚举常量名称,返回枚举实例

Color color = Color.valueOf("RED");
System.out.println(color.getValue());	// 输出:红
3)values()

遍历枚举类所有的枚举值

Color[] colors = Color.values();
for (Color color : colors) {
  System.out.println(color.name());
}
/*
输出:
RED
GREEN
BLUE
*/

注意:神秘的values()方法和valueOf(String)方法,这两个方法在其父类Enum中并不存在,那么它们哪里来的呢?答案是:它们是在创建枚举实例时,由编译器添加的static方法。

4)valueOf(Class enumType, String name)

此方法返回具有指定名称的指定枚举类型的枚举常量

Color color = Enum.valueOf(Color.class,"RED");
System.out.println(color.getValue());

区别valueOf(String name)与valueOf(Class enumType, String name)。前者是编译器添加的静态方法,后者是继承自Enum类的静态方法。

5)ordinal()

返回此枚举常量的序数(其枚举声明中的位置,其中初始常量被分配一个序号零)

Color color = Color.RED;
int ordinal = color.ordinal();
System.out.println(ordinal);					//输出:0
6)compareTo()

比较两个枚举值常量序数之差

Color color = Color.RED;
int n = color.compareTo(Color.BLUE) ;		//0 减 2
System.out.println(n);									//输出:-2 

五、应用案例

public enum ResponseCode {
    SUCCESS(200,"成功"),
    ILLEGAL_ARGUMENT(401,"无效参数"),
    NEED_LOGIN(403,"权限不够"),
		ERROR(500,"服务器错误");

    private final int code;
    private final String desc;

    ResponseCode(int code,String desc){
        this.code = code;
        this.desc = desc;
    }
    
    public int getCode(){
        return code;
    }
    public String getDesc(){
        return desc;
    }
}

在开发中枚举可以用来定义常量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WyuanY.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值