大家好,欢迎来到IT知识分享网。
目录
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中的枚举非常适合用来表示一组固定的常量,如星期、月份、菜单选项等。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/109784.html