🍊 枚举类理解
当我们需要的对象的个数只有有限个时,即对象的取值只在一个有限的集合内,且这些有限个对象都是确定的,针对于这种情况,我们可以自定义枚举类。
例如🌰,我们购买衣服时,对于衣服的尺码,有S、M、L、XL、XXL、XXXL,此时衣服的尺码的取值在一个有限的集合内,对于衣服的尺码,我们可以自定义一个枚举类,该枚举类的对象的值只有S、M、L、XL、XXL、XXXL有限个。
对于类的对象只有有限个,且该类的每个对象都是确定的,称这个类为枚举类。
例如🌰,季节这个枚举类,季节类的对象只有春季、夏季、秋季、冬季四个,季节类的对象为有限个且每个对象都是确定的。
当我们需要定义一组常量时,强烈建议使用枚举类。
若枚举只有一个对象, 则可以作为一种单例模式的实现方式。
注意,对于枚举类型的变量的取值,只能是枚举类中提供有限个对象或者是null。
🍊 自定义枚举类
自定义枚举类:
// 自定义枚举类 (季节类) class Season { // 1. 声明属性,使用 private final 修饰 // 由于枚举类的对象都是确定的,其属性值在对象创建之后也是确定的, // 一般枚举类的属性为常量,对象创建之后其属性值一般不会进行修改,也不允许修改。 private final String seasonName; private final String seasonDesc; // 2. 私有化构造器,并为对象属性赋值 // 由于枚举类的对象是确定的,所以不对外通过构造器 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 3. 提供当前枚举类的多个对象 // 由于枚举类只向外提供有限个的对象,不进行实例化, // 所以将有限个对象作为类属性向外暴露 // 使用 public static final 修饰 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("冬天", "冰天雪地"); // 4. 提供获取枚举类对象属性的方法 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } // 5. 提供重写的toString方法 @Override public String toString() { return "Season{" + "seasonName='" + seasonName + '\'' + ", seasonDesc='" + seasonDesc + '\'' + '}'; } }
测试自定义枚举类:
public class DefineEnum { public static void main(String[] args) { Season spring = Season.SPRING; System.out.println(spring); } }
🍊 使用 enum 关键字定义枚举类
enum Season{ // 1. 提供当前枚举类的对象 // 使用enum关键字定义枚举类,枚举类向外提供的对象必须定义在类的开始位置 // 且枚举类向外提供的对象不需要使用 “public static final 类名” 修饰 // 多个对象之间使用逗号进行分割,最后一个对象以分号结束 // 定义如下: SPRING("春天", "春暖花开"), SUMMER("夏天", "夏日炎炎"), AUTUMN("秋天", "秋高气爽"), WINTER("冬天", "冰天雪地"); // 2. 声明枚举类的属性 private final 修饰 // 由于枚举类的对象都是确定的,其属性值在对象创建之后也是确定的, // 一般枚举类的属性为常量,对象创建之后其属性值一般不会进行修改,也不允许修改。 private final String seasonName; private final String seasonDesc; // 3. 私有化构造器,并为对象属性赋值 // 由于枚举类的对象是确定的,所以不对外通过构造器 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 4. 提供获取枚举类对象属性的方法 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } }
注意,使用enum关键字定义的枚举类,默认继承于java.lang.Enum,即所有的使用enum关键字声明的枚举类都是Enum的子类,在Enum类中对toString方法进行了重写,Enum类中的toString方法返回的是枚举类对象的对象名。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; // enum定义的枚举类继承Enum, // Enum有重写toString方法,打印枚举类中对象的对象名 System.out.println(spring); // 查看Season类的父类 System.out.println(Season.class.getSuperclass()); } }
🍊 Enum类的常用方法
🥭 toString()
如果在使用enum关键字自定义的枚举类中没有重写toString()方法,则默认继承自Enum类的toString()方法,会得到当前枚举类常量对象的名称。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; System.out.println(spring); // 打印对象,默认自动调用toString方法 System.out.println(spring.toString()); } }
🥭 Enum.valueOf(Class enumClass, String name)
该方法可以根据指定的枚举类enumClass和枚举类常量的名称name获取匹配的枚举常量对象。
public class Test { public static void main(String[] args) { // Season.class 获取Season对应的Class类型的对象 Season spring = Enum.valueOf(Season.class, "SPRING"); System.out.println(spring); } }
🥭 valueOf(String name)
该方法可以根据指定的枚举类常量的名称,获取调用该方法的枚举类当中匹配的枚举常量对象。
public class Test { public static void main(String[] args) { Season spring = Season.valueOf("SPRING"); System.out.println(spring); } }
🥭 values()
该方法可以用于获取一个枚举类的全部枚举类常量对象,该方法返回的是该枚举类类型的所有枚举类常量对象组成的数组。
public class Test { public static void main(String[] args) { Season[] seasons = Season.values(); for (int i = 0; i < seasons.length; i++) { System.out.println(seasons[i]); } } }
🥭 name()
该方法可以用于获取当前枚举类常量对象的名称。
public class Test { public static void main(String[] args) { Season spring = Season.valueOf("SPRING"); System.out.println(spring); System.out.println(spring.name()); } }
🥭 ordinal()
该方法可以用于获取当前枚举类常量对象的次序。枚举类常量对象的次序是按照枚举类常量对象在枚举类中声明的位置顺序进行编排的,从0开始计数。
枚举类中声明的位置顺序:
SPRING("春天", "春暖花开"), SUMMER("夏天", "夏日炎炎"), AUTUMN("秋天", "秋高气爽"), WINTER("冬天", "冰天雪地");
public class Test { public static void main(String[] args) { Season spring = Season.valueOf("SPRING"); System.out.println(spring); System.out.println(spring.ordinal()); } }
🥭 compareTo()
该方法可以用于比较一个枚举类中的枚举类常量对象的大小,比较枚举类常量对象的大小是根据枚举类常量对象在枚举类中的声明次序进行比较的,先声明的枚举类常量对象比后声明的小,即次序小的小。
该方法的返回值为进行比较的两个枚举类常量对象的次序的差,用调用该方法的枚举类常量对象的次序减去方法中传入的枚举类常量对象的次序。
public class Test { public static void main(String[] args) { Season spring1 = Season.SPRING; Season spring2 = Season.SPRING; Season summer = Season.SUMMER; Season autumn = Season.AUTUMN; System.out.println(spring1.compareTo(spring2)); // 0-0 System.out.println(spring1.compareTo(summer)); // 0-1 System.out.println(spring1.compareTo(autumn)); // 0-2 } }
🥭 equals()
该方法用于比较两个枚举类常量对象是否相等,即判断是否为同一个枚举类常量对象。如果相等则返回true,否则返回false。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season summer = Season.SUMMER; Season autumn = Season.AUTUMN; Size s = Size.S; System.out.println(s.equals(s)); System.out.println(s.equals(spring)); System.out.println(spring.equals(summer)); } } enum Size { S, M, L, XL, XXL, XXXL }
比较两个枚举类常量对象是否相等,也可以直接使用==
,因为枚举类常量对象只在枚举类被加载时进行了创建。但是使用==
比较两个枚举类常量对象只能比较相同类型的枚举类常量对象。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season summer = Season.SUMMER; Season autumn = Season.AUTUMN; Size s = Size.S; System.out.println(s == s); // System.out.println(s == spring); System.out.println(spring == summer); } }
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season summer = Season.SUMMER; Season autumn = Season.AUTUMN; Size s = Size.S; System.out.println(s == s); System.out.println(s == spring); System.out.println(spring == summer); } }
🥭 getDeclaringClass()
该方法可以用于获取枚举类常量对象的所属枚举类的Class对象。可以用获取的所属枚举类的Class对象判断两个枚举类常量对象是否属于同一个枚举类。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season summer = Season.SUMMER; Size s = Size.S; System.out.println(spring.getDeclaringClass()); System.out.println(summer.getDeclaringClass()); System.out.println(s.getDeclaringClass()); System.out.println(spring.getDeclaringClass().equals(s.getDeclaringClass())); System.out.println(spring.getDeclaringClass().equals(summer.getDeclaringClass())); } }
🥭 hashCode()
该方法可以用于获取枚举类常量对象的hashCode值。由于枚举类常量对象只在枚举类被加载时进行了创建,所以枚举类常量对象的hashCode值在创建之后就是固定不变的。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season summer = Season.SUMMER; Size s = Size.S; System.out.println(spring.hashCode()); System.out.println(summer.hashCode()); System.out.println(s.hashCode()); } }
🥭 clone()
枚举类常量对象不能被克隆,为了防止Enum子类实现克隆方法,Enum实现了一个仅抛出CloneNotSupportedException异常的clone()方法。
🍊 使用enum关键字定义的枚举类实现接口
🥭 实现接口,在enum类中实现抽象方法
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; spring.show(); } } // 接口 interface Info{ void show(); } enum Season implements Info{ // 1. 提供当前枚举类的对象 SPRING("春天", "春暖花开"), SUMMER("夏天", "夏日炎炎"), AUTUMN("秋天", "秋高气爽"), WINTER("冬天", "冰天雪地"); // 2. 声明枚举类的属性, private final 修饰 private final String seasonName; private final String seasonDesc; // 3. 私有化构造器,并为对象属性赋值 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 4. 提供获取枚举类对象属性的方法 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } // 5. 接口方法的实现 @Override public void show() { System.out.println("现在的季节是:" + this.seasonName); } }
🥭 枚举类的对象分别实现接口的抽象方法
对于枚举类,可以在每个枚举类常量对象中单独实现接口中的方法,这样每个枚举类常量对象都有属于自己的对于接口方法的实现逻辑,可以实现不同枚举类常量对象相同接口方法有不同的运行逻辑。
public class Test { public static void main(String[] args) { Season spring = Season.SPRING; Season[] seasons = Season.values(); for (int i = 0; i < seasons.length; i++) { seasons[i].show(); } } } interface Info{ void show(); } enum Season implements Info{ // 1. 提供当前枚举类的对象,每个枚举类常量对象单独实现接口 SPRING("春天", "春暖花开"){ @Override public void show() { System.out.println("春天spring"); } }, SUMMER("夏天", "夏日炎炎"){ @Override public void show() { System.out.println("夏天summer"); } }, AUTUMN("秋天", "秋高气爽"){ @Override public void show() { System.out.println("秋天autumn"); } }, WINTER("冬天", "冰天雪地"){ @Override public void show() { System.out.println("冬天winter"); } }; // 2. 声明类的属性, private final 修饰 private final String seasonName; private final String seasonDesc; // 3. 私有化构造器,并为对象属性赋值 private Season(String seasonName, String seasonDesc) { this.seasonName = seasonName; this.seasonDesc = seasonDesc; } // 4. 提供获取枚举类对象属性的方法 public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } }