java中的枚举

目录

一、什么是枚举?

二、枚举进化史

进化1.0

进化2.0

枚举的诞生3.0

三、枚举语法

四、枚举常用API

1)name()

2)valueOf(String name)

3)values()

4)valueOf(Class enumType, String name)

5)ordinal()

6)compareTo()

五、总结


一、什么是枚举?

       介绍:java中枚举类属于一种特殊的数据类型,用于定义一组常量。枚举类型可以帮助我们组织和管理相关的常量,使得代码更加清晰、可读性更强。

       抛出一个问题:java数据类型这么多,为什么还要来一个枚举?

枚举核心:枚举的核心是将一组相关的常量封装在一个类型安全的枚举中,使得代码更加清晰、可读、可维护,同时提供了更多类型安全的保障。在实际开发中,枚举常常用于表示一组相关的常量,例如表示一周的天数、表示颜色、表示状态等等

二、枚举进化史

假设现在有一个需求:统计学生分数,并且评判等级,A级、B级、C级

进化1.0

在没有枚举之前,我们应该会是这样写的

一、封装学生类

public class Student {
	//姓名
	private String name ;
	//等级:必须只能是 A B C 三种级别
	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("[ABC]")) {
			throw new RuntimeException("等级只能是A B C") ;
		}
		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("A");
		System.out.println(stu);
	}
}

        这里达到了分数只能是A、B、C三种等级的效果,但是setGrade什么都可以放,可以说是个字符串就可以放进去,这样做确实可以,但是吧总感觉不是很文雅,最好就是类似前端的下拉选择框一样,有什么数据,那就指定选什么数据

开始进化:把等级封装为一个类

进化2.0

第一:封装等级

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("中等");
	
	@Override
	public String toString() {
		return this.value;
	}
}

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

public class Student {
	// 姓名
	private String name ;
	// 等级:必须只能是 A B C 三种级别
	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);
	}
}

OK,目前就已经达到选择效果,有什么级别,那就只能选什么级别

枚举的诞生3.0

枚举实现,将等级放进枚举类中。

第一、定义枚举类

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

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

第二、改进Grade枚举—指定A、B、C五个等级对应的中文表示和分数范围

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";
		}
	};
  
	// 定义属性:表示等级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("静态方法");
  }
}

        A("优秀"),里面的 参数由构造方法提供,如果你想写其他的比如A("优秀",100),那么构造就可以在加上一个int

第三、测试

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 枚举类名 {
  // 枚举常量 - 枚举实例(枚举值)
  
  // 成员变量、常量
  // 成员方法、抽象方法、静态方法、重载方法、重写方法
  // 构造方法
}

四、枚举常用API

1)name()

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

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

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

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

遍历枚举类所有的枚举值

1
2
3
4
5
6
7
8
9
10
Color[] colors = Color.values();
for (Color color : colors) {
  System.out.println(color.name());
}
/*
输出:
RED
GREEN
BLUE
*/

注意:在Java中,枚举的values()方法和valueOf(String)方法非常特殊。这两个方法对于每个枚举类都是可用的,但它们不是从java.lang.Enum类继承来的,也不会在枚举类的代码中明显地看到它们的定义。这是因为这些方法是在编译时由Java编译器自动为每个枚举类隐式添加的。

4)valueOf(Class enumType, String name)

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

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

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

5)ordinal()

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

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

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

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

五、总结

  1. 类型安全:枚举确保只能接受预定义的常量值,这使得代码更加安全、清晰和易于维护。这种类型安全特性避免了传统的int常量带来的类型安全问题。

  2. 固定实例:枚举的每个元素都是枚举类型的一个实例。当枚举被编译时,每个枚举常量都会被实例化成为枚举类型的一个固定实例。

  3. 易于使用:Java的枚举可以很方便地使用switch语句进行条件判断,而不需要使用多个if-else语句。

  4. 扩展性:尽管枚举不能继承其他类(枚举都隐式继承了java.lang.Enum),但可以实现接口,并可以定义属性和方法。这使得它们比传统的基于整数的常量更加灵活和功能丰富。

  5. 单例模式:每个枚举常量都通过public static final修饰,是单例的。在整个程序中,每个枚举常量只有一个实例,这类似于单例模式。

  6. 内置方法:枚举类提供了一些内置方法,如values()ordinal()valueOf()等。values()返回包含所有枚举常量的数组,ordinal()方法返回枚举常量的序号,而valueOf()方法可以将字符串转换为对应的枚举常量。

  7. 自定义构造器:你可以为枚举类定义一个或多个构造器,以及字段和方法。这些构造器只能是包级私有或私有的,确保不能从枚举类型外部创建枚举实例。

这些特点使得Java中的枚举非常适合用来表示一组固定的常量,如星期、月份、菜单选项等。

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值