一、文章序言
Java中引用类型:数组、类、接口、枚举、注解
枚举这个既熟悉又陌生的东西具体再哪里可以使用呢?
什么是枚举?
枚举是一个引用类型,枚举就是一个规定了取值范围的变量类型。
枚举变量不能使用其他的数据,只能使用枚举中常量赋值。提高程序安全性;
//格式: public enum 枚举名{ //枚举的取值范围 //枚举中可以生命方法 }
枚举的使用场景介绍?
1、最常见的情况如星期,相关变量我们会在Java里面重复使用,在这里我们就可以来定义一个叫做“星期”的枚举。
public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FRIDAY, SATURDAY }
如果不定义成枚举,各位的写法就千奇百怪了,比如“周一”、“星期一”、“Monday”等,写法千奇百怪,定义枚举一目了然。
2、比如说季节的春夏秋冬,我们同样可以定义一个这样的变量来存储对应的季节。
public enum Season { SPRING, SUMMER, AUTUMN, WINTER; }
3、英雄联盟里面,有很多职业,比如说”战士“、”法师“、”射手“……等职业。我们就可以定义一个叫”职业“的枚举类型;后台再其它地方哪里需要直接引用即可;
总结:枚举里面定义的就相当于是已经生成且固定的对象,你可以直接使用;如果Java代码里面与如上需要定义的常量可以直接定义一个枚举类;
定义枚举类型时本质上就是定义一个类别,只不过很多细节由编译器帮我们完成了,所以某些程度上,enum关键字的作用 就像是class或interface
1 枚举的本质:其实就是终止类,并继承Enum抽象类。
2 枚举中的变量,其实就是一个当前类型的静态常量。
解释:
当我们使用“enum”定义枚举类型时,实质上我们定义出来的类型继承自java.lang.Enum类型,而枚举的成员其实就是我们定义的枚举类型的一 个实例(Instance),他们都被预设为final,所以我们无法改变他们,他们也是static成员,所以我们可以通过类型名称直接使用他们,当然最重要的,他们都是公开的(public)。
二、代码实践
先定义一个枚举:季节枚举
//声明一个表示季节的枚举 public enum Season { SPRING, SUMMER, AUTUMN, WINTER; }
枚举可以搭配switch语句使用:案例如下
public class TestSeasonEnum { public static void main(String[] args) { Season season = Season.SPRING; //switch小括号中的表达式类型可以是枚举类型 switch(season){ //每个case后的常量直接写枚举的取值范 case SPRING: System.out.println("春天"); break; case SUMMER: System.out.println("夏天"); break; case AUTUMN: System.out.println("秋天"); break; case WINTER: System.out.println("冬天"); break; } } }
输出结果
春天
为了加深理解,再举例一个错误的用法
An enum switch case label must be the unqualified name of an enumeration constant
注意,在switch中,不能使用枚举类名称,因为编译器会根据switch()的类型来判定每个枚举类型,在case中必须直接给出与()相同类型的枚举选项,而不能再有类型。
代码如上可以直接测试,建议实测
三、面试相关
来来来,刚好抽时间一起整理一下常见面试问题吧,然后相关解析已经附上详细代码学习,实践实践再实践!
1.枚举允许继承类吗?
枚举类使用enum定义后在编译后默认继承了java.lang.Enum类,而不是普通的继承Object类。enum声明类继承了Serializable和Comparable两个接口。且采用enum声明后,该类会被编译器加上final声明(同String),故该类是无法继承的。
所有枚举类都默认是Enum类的子类,无需我们使用extends来继承。
2.枚举允许实现接口吗?
枚举允许实现接口。因为枚举本身就是一个类,类是可以实现多个接口的。
public interface EnumInterface { public abstract void print(); }
public enum SizeEnum implements EnumInterface{ BIG,MIDDLE,SMALL; @Override public void print() { System.out.println("继承接口-重写方法一次"); } }
3.枚举可以用等号比较吗?
肯定,因为在Enum类里面,已经重写了equals方法,而方法里面比较就是直接使用==,来比较2个对象的。所以,你在外边直接使用==也是可以的。
4.可以继承枚举吗?
当然不能呀,枚举类默认继承了java.lang.Enum类,一个类怎么能继承两个类呢?
5.枚举可以实现单例模式吗?
枚举本身就是一种对单例设计模式友好的形式,它是实现单例模式的一种很好的方式。
public class InstanceDemo { /** * 构造方法私有化 */ private InstanceDemo(){ } /** * 返回实例 * @return */ public static InstanceDemo getInstance() { return Singleton.INSTANCE.getInstance(); } /** * 使用枚举方法实现单利模式 */ private enum Singleton { INSTANCE; private InstanceDemo instance; /** * JVM保证这个方法绝对只调用一次 */ Singleton() { instance = new InstanceDemo(); } public InstanceDemo getInstance() { return instance; } } //测试一下 public static void main(String[] args) { InstanceDemo one = InstanceDemo.getInstance(); InstanceDemo two = InstanceDemo.getInstance(); System.out.println(one); System.out.println(two); System.out.println(one == two); } }
创建的对象相同
csdn.test.recursion.demo.InstanceDemo@74a14482 csdn.test.recursion.demo.InstanceDemo@74a14482 true
6.当使用compareTo()比较枚举时,比较的是什么?
int compareTo(E e):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序;返回值可以仔细看看源码;
一起看看,底层代码吧
public final int compareTo(E o) { Enum<?> other = (Enum<?>)o; Enum<E> self = this; if (self.getClass() != other.getClass() && // optimization self.getDeclaringClass() != other.getDeclaringClass()) throw new ClassCastException(); return self.ordinal - other.ordinal; }
举个例子你就能理解了
public class TestSeasonEnum { public static void main(String[] args) { Season season = Season.SPRING; Season season1 = Season.SUMMER; Season season2 = Season.AUTUMN; Season season3 = Season.WINTER; System.out.println(season.compareTo(season1)); System.out.println(season.compareTo(season2)); System.out.println(season.compareTo(season3)); } }
输出结课,详情参考源码一看便知道
-1
-2
-3
7. 当使用equals()比较枚举的时候,比较的是什么?
枚举类型的equals()方法比较的是枚举类对象的内存地址,作用与等号等价。
到此这篇关于Java基础之枚举Enum类案例详解的文章就介绍到这了,更多相关Java枚举Enum类内容请搜索自学编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持自学编程网!
- 本文固定链接: https://zxbcw.cn/post/211565/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)