首页 > 基础资料 博客日记
java中的枚举
2024-08-20 20:00:08基础资料围观171次
目录
4)valueOf(Class enumType, String name)
一、什么是枚举?
介绍: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 |
五、总结
-
类型安全:枚举确保只能接受预定义的常量值,这使得代码更加安全、清晰和易于维护。这种类型安全特性避免了传统的int常量带来的类型安全问题。
-
固定实例:枚举的每个元素都是枚举类型的一个实例。当枚举被编译时,每个枚举常量都会被实例化成为枚举类型的一个固定实例。
-
易于使用:Java的枚举可以很方便地使用
switch
语句进行条件判断,而不需要使用多个if-else
语句。 -
扩展性:尽管枚举不能继承其他类(枚举都隐式继承了
java.lang.Enum
),但可以实现接口,并可以定义属性和方法。这使得它们比传统的基于整数的常量更加灵活和功能丰富。 -
单例模式:每个枚举常量都通过
public static final
修饰,是单例的。在整个程序中,每个枚举常量只有一个实例,这类似于单例模式。 -
内置方法:枚举类提供了一些内置方法,如
values()
,ordinal()
和valueOf()
等。values()
返回包含所有枚举常量的数组,ordinal()
方法返回枚举常量的序号,而valueOf()
方法可以将字符串转换为对应的枚举常量。 -
自定义构造器:你可以为枚举类定义一个或多个构造器,以及字段和方法。这些构造器只能是包级私有或私有的,确保不能从枚举类型外部创建枚举实例。
这些特点使得Java中的枚举非常适合用来表示一组固定的常量,如星期、月份、菜单选项等。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: