一,枚举的使用
1.枚举的引入
案例:
java
//案例:枚举的引入
//需求:编写季节类(season),该类只有四个对象(Spring,summer,autumn,winter)
public class Test01{
public static void main(String[] args){
Season spring =Season.spring;
Season summer =Season.summer;
Season autumn =Season.autumn;
Season winter =Season.winter;
sout(spring);
sout(summer);
sout(autumn);
sout(winter);
}
}
public class season{
public static final Season Spring = new Season("春天","万物复苏");
public static final Season summer = new Season("夏天","挥汗如雨");
public static final Season autumn = new Season("秋天","秋高气爽");
public static final Season winter = new Season("冬天","银装素裹");//这些相当于该类的属性,使用public以便外界的包可以使用,使用static为静态属性,让外界可以直接使用类名去调用(因为下面私有化属性了,无法new对象),使用final修饰,使其变成常量,因为题目是"让该类只有四个对象",使其无法再为对象赋值
private String name;
private String info;
private Season(){
}
private Season(String name,String info){
this.name=name;
this.info=info;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
经验:一个类有固定几个对象,就用枚举代替
理解:
枚举就是一个特殊的类,但是他也是引用数据类型的一种
枚举代码实现:
java
public enum Season{
//注意:枚举类第一行必须声明对象
//注意:枚举对象默认使用public static final修饰 -- public static final Season spring = new Season("春天","春雨绵绵");
spring("春天","春雨绵绵");
spring("夏天","烈日炎炎");
spring("秋天","硕果累累");
spring("冬天","白雪皑皑");
private String name;
private String info;
//注意:枚举类的构造方法都是私有的
private Season() {
}
private Season(String name, String info) {
this.name = name;
this.info = info;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return name + " -- " + info;
}
}
public class Test01{
public static void main(String[] args) {
Season spring = Season.spring;
Season summer = Season.summer;
Season autumn = Season.autumn;
Season winter = Season.winter;
System.out.println(spring);
System.out.println(summer);
System.out.println(autumn);
System.out.println(winter);
}
}
注意:
枚举就是一个特殊的类,但是他也是引用数据类型的一种
枚举没有显示继承
枚举有隐式继承 -> Season extends Enum extends Object
概念
枚举(enum)全称为 enumeration, 是 JDK 1.5 中引入的新特性。
特点
枚举就是一个受限制的类,默认继承Enum
枚举的第一行必须定义该枚举类型的对象
枚举类型对象默认添加: public static final 类型
枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
枚举类不能被继承
枚举里可以有构造方法、成员方法、静态方法、抽象方法
枚举可以实现接口
枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
优势
增强代码可读性
枚举型可直接与数据库交互
switch语句优势
编译优势
(枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )
将常量组织起来,统一管理
去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过"=="进行两个值之间的对比,性能会有所提高
枚举的方法 :
java
public class Test02 {
/**
* 知识点:枚举的常用方法
*/
public static void main(String[] args) {
//通过字符串获取枚举类中的对象
Season season1 = Enum.valueOf(Season.class, "spring");
System.out.println(season1);
//通过字符串获取枚举类中的对象
Season season2 = Season.valueOf("spring");
System.out.println(season2);
//获取Season枚举类中所有的对象,返回数组
Season[] values = Season.values();
for (Season season : values) {
System.out.println(season);
}
}
}
switch 表达式支持 byte short int char 枚举 String
手撕枚举底层源码:
java
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
private final String name;//枚举对象名
private final int ordinal;//枚举编号(从0开始)
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
}
java
//枚举本质意义上就是一个类,默认继承Enum
public final class Season extends Enum{
public static final Season spring;
public static final Season summer;
public static final Season autumn;
public static final Season winter;
private String name;
private String info;
//存放该枚举类的所有对象 -- 数组
private static final Season[] ENUM$VALUES;
//静态代码块(初始化枚举对象、将枚举对象存入ENUM$VALUES数组中)
static{
spring = new Season("spring", 0, "春天", "春雨绵绵");
summer = new Season("summer", 1, "夏天", "烈日炎炎");
autumn = new Season("autumn", 2, "秋天", "硕果累累");
winter = new Season("winter", 3, "冬天", "白雪皑皑");
ENUM$VALUES = (new Season[] {
spring, summer, autumn, winter
});
}
//改造了我们写的无参构造 -- private Season(){}
private Season(String s, int i){
super(s, i);
}
//改造了我们写的有参构造 -- private Season(String name,String info){}
private Season(String s, int i, String name, String info){
super(s, i);
this.name = name;
this.info = info;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getInfo(){
return info;
}
public void setInfo(String info){
this.info = info;
}
public String toString(){
return (new StringBuilder(String.valueOf(name))).append(" -- ").append(info).toString();
}
public static Season[] values(){
Season[] aseason = ENUM$VALUES;//获取ENUM$VALUES
int i = aseason.length;//i - 4
//创建了一个与ENUM$VALUES长度相同的数组
Season[] aseason1 = new Season[i];
System.arraycopy(aseason, 0, aseason1, 0, i);
return aseason1;
}
public static Season valueOf(String s)
{
return (Season)Enum.valueOf(com/qf/enum02/Season, s);
}
}
switch判断枚举底层源码
java
public class Test03{
private static int[] $SWITCH_TABLE$com$qf$enum02$Season;//[1,2,3,4]
public static void main(String args[]){
//[1,2,3,4]
int[] ai = $SWITCH_TABLE$com$qf$enum02$Season();
switch (ai[Season.spring.ordinal()]){//ai[0] -- 1
case 1: // '\001'
System.out.println("春天");
break;
case 2: // '\002'
System.out.println("夏天");
break;
case 3: // '\003'
System.out.println("秋天");
break;
case 4: // '\004'
System.out.println("冬天");
break;
}
}
static int[] $SWITCH_TABLE$com$qf$enum02$Season(){
//[0,0,0,0]
int[] ai = new int[Season.values().length];//Season.values().length - 4
try{
//Season.autumn.ordinal() -- 2
ai[Season.autumn.ordinal()] = 3;//ai[2] = 3;
}catch (NoSuchFieldError ) { }
try{
//Season.spring.ordinal() - 0
ai[Season.spring.ordinal()] = 1;//ai[0] = 1
}catch (NoSuchFieldError ) { }
try{
//Season.summer.ordinal - 1
ai[Season.summer.ordinal()] = 2;//ai[1] = 2
}catch (NoSuchFieldError ) { }
try{
//Season.winter.ordinal() - 3
ai[Season.winter.ordinal()] = 4;//ai[3] = 4
}catch (NoSuchFieldError ) { }
//ai -> [1,2,3,4]
return $SWITCH_TABLE$com$qf$enum02$Season = ai;
}
}
枚举案例之--状态机
java
//信号灯的枚举
public enum Signal {
RED,YELLOW,GREEN;
}
public class Test01{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("请选择型号灯: RED,YELLOW,GREEN");
String str = scan.next();
Signal signal= Signal.valueOf(str);//枚举中的方法,获取信号灯的对象
String trafficInstruct = getTrafficInstruct(signal);
System.out.println(trafficInstruct);
sacn.close();
}
}
public static String getTrafficInstruct(Signal signal){
String instruct = "信号灯故障";
switch (signal){
case RED:
instruct ="红灯停";
break;
case YELLOW:
instruct ="黄灯请注意";
break;
case GREEN:
instruct ="绿灯行";
break;
}
return instruct;
}