枚举
概念
枚举是一种特殊的数据类型。枚举类不能实例化
(但可以通过反射获取)也不能被继承
,也不能被实现
。可以有构造方法(默认私有)当需要定义一组常量时,强烈建议使用枚举类(比如一年有四季,一周有七天,这些都可以使用枚举)
枚举的定义
在没有枚举类型时定义常量常见的方式
最初定义枚举类举例
public static final int MON=1;
public class SeansonTest {
public static void main(String[] args) {
Season p = Season.S;
Season p1 = Season.M;
Season p2 = Season.A;
Season p3 = Season.W;
System.out.println(p);
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
}
}
class Season {
//声明Season对象的属性:private final修饰
private final String seasonName;
private final String seansonshow;
//私有化类的构造器,并给对象赋值
private Season(String seasonName, String seansonshow) {
this.seasonName = seasonName;
this.seansonshow = seansonshow;
}
//提供当前枚举的多个对象
public static final Season S = new Season("春天", "漂亮");
public static final Season M = new Season("夏天", "漂亮");
public static final Season A = new Season("秋天", "漂亮");
public static final Season W = new Season("冬天", "漂亮");
//获取枚举对象的属性
public String getSeasonName() {
return seasonName;
}
public String getSeansonshow() {
return seansonshow;
}
//提供toString()
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seansοnshοw='" + seansonshow + '\'' +
'}';
}
}
//输出结果:
Season{
seasonName='春天', seansonshow='漂亮'}
Season{
seasonName='夏天', seansonshow='漂亮'}
Season{
seasonName='秋天', seansonshow='漂亮'}
Season{
seasonName='冬天', seansonshow='漂亮'}
使用关键字enum
来定义枚举
//枚举类型,使用关键字enum
enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY//枚举实例一般都是大写的字母
}
public enum EnumTest {
ONE,//假如后面什么都没有(属性或者方法),可以不加分号或者逗号(加也可以)且多个实例用逗号隔开,有实例必须放在首行代码
Two;
//枚举可以有方法、字段(属性)、内部类
public String name="abc";
}
public class EnTest {
public static void main(String[] args) {
System.out.println(EnumTest.ONE);//ONE返回当前EnumTest实例(//这里相当于调用了对象的toString()方法)
}
}
//输出结果:ONE
public class SeansonTest {
public static void main(String[] args) {
Season p = Season.S;
Season p1 = Season.M;
System.out.println(p);
System.out.println(p1);
}
}
//使用enum关键字枚举类(定义的枚举类默认继承java.lang.Enum类)
enum Season {
//提供当前枚举的对象,多个对象之间用”,“隔开,末尾的对象”;“结束
S("春天", "漂亮"),
M("夏天", "漂亮"),
A("秋天", "漂亮"),
W("冬天", "漂亮");
private final String seasonName;
private final String seansonshow;
private Season(String seasonName, String seansonshow) {
this.seasonName = seasonName;
this.seansonshow = seansonshow;
}
public String getSeasonName() {
return seasonName;
}
public String getSeansonshow() {
return seansonshow;
}
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seansοnshοw='" + seansonshow + '\'' +
'}';
}
}
Season{
seasonName='春天', seansonshow='漂亮'}
Season{
seasonName='夏天', seansonshow='漂亮'}
枚举还可以使 switch
语句的可读性更强
public enum EnumTest {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY;
}
public class EnTest {
public static void main(String[] args) {
show(EnumTest.MONDAY);
}
public static void show(EnumTest e) {
switch (e) {
case MONDAY:
System.out.println("周一");
break;
case TUESDAY:
System.out.println("周二");
break;
case WEDNESDAY:
System.out.println("周三");
break;
case THURSDAY:
System.out.println("周四");
break;
case FRIDAY:
System.out.println("周五");java
break;
case SATURDAY:
System.out.println("周六");
break;
}
}
}
//输出结果:周一
枚举类实现接口
interface Mul {
void show();
}
enum Season implements Mul {
}
//实现接口的枚举类
public class SeansonTest {
public static void cmain(String[] args) {
Season p = Season.S;
Season p1 = Season.M;
System.out.println(p);
System.out.println(p1);
}
}
interface Mul {
void show();
}
//使用enum关键字枚举类(定义的枚举类默认继承java.lang.Enum类)
enum Season implements Mul {
w
//提供当前枚举的对象,多个对象之间用”,“隔开,末尾的对象”;“结束
S("春天", "温暖") {
@Override
public void show() {
System.out.println("艾伦~");
}
},
M("夏天", "酷暑") {
@Override
public void show() {
System.out.println("我一定要驱赶所有的巨人");
}
},
A("秋天", "飒爽") {
@Override
public void show() {
System.out.println("绝对~");
}
},
W("冬天", "刺骨") {
@Override
public void show() {
System.out.println("啪~艾伦你醒醒");
}
};
private final String seasonName;
private final String seansonshow;
private Season(String seasonName, String seansonshow) {
this.seasonName = seasonName;
this.seansonshow = seansonshow;
}
public String getSeasonName() {
return seasonName;
}
public String getSeansonshow() {
return seansonshow;
}
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seansοnshοw='" + seansonshow + '\'' +
'}';
}
@Override
public void show(){
System.out.println("我是接口方法");
}
}
枚举类中的抽象方法
我们知道如果一个类有抽象方法那么它一定是个抽象类,而抽象类不一定有抽象方法,抽象类就需要子类继承它然后实现它的抽象方法。enum
类允许我们定义其抽象方法,然后每个枚举实例都实现该抽象方法
public enum Colorenum {
RED{
@Override
public String getColorNane() {
return "红色";
}
},
YELLOW{
@Override
public String getColorNane() {
return "黄色";
}
};
public abstract String getColorNane();
public static void main(String[] args) {
System.out.println(Colorenum.RED.getColorNane());
}
}
//输出结果:红色
//通过这种方式可以自定义每个枚举的实例的行为方式
枚举类
Java 中的每一个枚举都继承自 java.lang.Enum
类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum
类的实例,这些枚举成员默认都被 final
、public
, static
修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可
Enum
类的主要方法
方法 | 说明 |
---|---|
protected Enum(String name,int ordinal) |
此构造方法不能被外部直接调用,只能被其子类访问,此构造方法为自动调用 |
values() |
返回枚举类型的对象数组(遍历所有的枚举值) |
valueOf(String str) |
可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常: IllegalArgumentException |
toString() |
返回当前枚举类对象常量的名称 |
compareTo() |
默认按照枚举对象的顺序排序 |
ordinal() |
获取枚举成员的索引位置 |
name()
方法与toString()
几乎是等同的,底层源码调用的的都是父类的返回的name
public enum EnumTest {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnTest {
public static void main(String[] args) {
//name()方法与toString()几乎是等同的,底层源码返回的都是name
System.out.println(EnumTest.MONDAY.name());
System.out.println(EnumTest.MONDAY.toString());
System.out.println(EnumTest.MONDAY.ordinal());//索引是从0开始
System.out.println(EnumTest.MONDAY.getClass());
System.out.println(EnumTest.MONDAY.getDeclaringClass());
System.out.println(EnumTest.MONDAY.valueOf("TUESDAY"));
//该方法形参只要一个String类型的值,并且该String值为枚举值对应的名称,即toString()方法返回的值(比如枚举类为SPRING,对应的名称就是"SPRING")
}
}
/*
输出结果:
MONDAY
MONDAY
0
class java_11.EnumTest
class java_11.EnumTest
TUESDAY
*/
枚举类集合
在JDK1.5之后,新出了Set
和Map
接口而言又增加了2个新的子类:EnumSet
、EnumMap
方法 | 说明 |
---|---|
allOf(Class element type) |
创建一个包含指定枚举类型中所有枚举成员的 EnumSet 对象 |
complementOf(EnumSet s) |
创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象,并包含所有 s 中未包含的枚举成员 |
copyOf(EnumSet s) |
创建与指定的枚举集相同的元素类型的枚举集,最初包含相同的元素(如果有)。 |
noneOf(<Class elementType) |
创建指定枚举类型的空 EnumSet 对象 |
of(E first,e…rest) |
创建包含指定枚举成员的 EnumSet 对象 |
range(E from ,E to ) |
创建一个 EnumSet 对象,该对象包含了 from 到 to 之间的所有枚举成员 |
public enum Weekday {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
class Test2 {
public static void main(String[] args) {
EnumSet<Weekday> set=EnumSet.allOf(Weekday.class);
for (Weekday weekday : set) {
System.out.println(weekday);
}
EnumMap<Weekday,String> map=new EnumMap<>(Weekday.class);
map.put(Weekday.MONDAY,"周一");
Set<Map.Entry<Weekday, String>> entries = map.entrySet();
for (Map.Entry<Weekday, String> entry : entries) {
System.out.println(entries);
}
}
}
/*
输出结果:MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
[MONDAY=周一]
*/
小结
- 使用枚举的关键字是
enum
,不是class
(也就是说使用enum
关键字定义的枚举类,实际上就是定义了一个枚举类,只不过这个类继承了Enum
类) - 枚举变量最好都是大写字母,且多个单词用
_
隔开 - 定义完所有的变量用
;
隔开。如果枚举只定义了枚举变量,而没有自定义变量,则分号可以省略
public enum EnumTest {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
- 构造函数必须私有化。可以省略
private
,因为它默认并强制是private
,如果你要写,也只能写private
,写public
编译器不会通过
public enum Colorenum {
RED("红色"),YELLOW("黄色"),BLUE("蓝色");
private String color;
private Weekday(String s){
this.color=s;
}
}