enum 枚举类

枚举类介绍

如果一个类的实例是有限且确定的,那么可以使用枚举类。比如:季节类,只有春夏秋冬四个实例

枚举类使用enum进行创建,其实例必须从”第一行“开始显示写出。

enum Season{
   SPRING,SUMMER,FALL,WINTER;//默认public static final,这都是Season类的对象。
}

特点

1、枚举类的对象默认都是public static final

2、枚举类的构造器都是private,所以无法在外部创建其实例,这也决定了枚举类实例的个数的确定性(写了几个就是几个)。

3enum类不可被继承。

4enum类默认extends java.lang.Enum,所以无法再继承其他类

在这里插入图片描述

问题

enum类默认被final修饰的情况下,是无法有子类的

《疯狂Java讲义》中
在这里插入图片描述

@Getter
enum Season{
//    SPRING,SUMMER,FALL,WINTER;//默认public static final,这都是Season类的对象。
    SPRING{
        public void show(){
            System.out.println("I'm Spring");
        }
    },SUMMER,FALL,WINTER;
    private String name;
    //构造器默认且只能是private
    Season(){
        System.out.println("Season run...");//运行四次
    }
    public void setName(){
        //Java5开始,switch方法支持枚举类对象。
        switch(this){
            case SPRING:
                name="春";
                break;
            case SUMMER:
                name="夏";
                break;
            case FALL:
                name="秋";
                break;
            case WINTER:
                name="冬";
                break;
        }
    }
    public void setName1(String name){
        this.name=name;
    }
    public void show(){
        System.out.println("I'm show");
    }
}  

在这里插入图片描述

问题:SPRINGSeason匿名子类的对象,但是前面已经说明Season类是final的?

1、当在enum类创建匿名子类对象的时候,在运行时,会将Season编译为一个.class文件没有final修饰
在这里插入图片描述
同时对于匿名子类,会生成一个.class文件:
在这里插入图片描述
2、当enum类中没有匿名子类对象时,对应的class就是final的
在这里插入图片描述
3、如果enum类中含有抽象方法,那么这个类就是抽象的:给出的对象必须实现抽象方法
在这里插入图片描述
在这里插入图片描述
即便如此,还是无法继承该类
在这里插入图片描述

结论

1、enum类实际上是不存在final或者abstract的,就是不能被继承。如果像《疯狂Java讲义》中说的,非抽象枚举类默认是final的,那么应该可以显示用final修饰,但是不行:
在这里插入图片描述
在这里插入图片描述
所以说,enum本身不存在final、abstract的说法。就是不能被继承运行时生成的class才有final、abstract的说法

2、运行时,会生成对应的.class文件(可以理解为一个新的class类型的类)。

如果enum类中 没有抽象方法 ,也 没有匿名子类对象 ,那么这个类是被 final修饰 的。

如果enum类中 有抽象方法 ,那么 这个类是抽象的 ,对象 必须实现 该抽象方法。

如果enum类中 没有抽象方法 ,但是 有匿名子类对象 ,那么 这个类不被final修饰,也不是抽象的

实战

注入整个包

在使用 enum 类中的静态方法或者 enum 枚举时,可以直接把 enum 整个包 import

@Getter
@AllArgsConstructor
public enum HumanTypeEnum {

    MAN(0, "男"),
	FEMALE(1, "女")

    private int type;
    private String remark;

    public static String getValue(String type) {
        ....
    }

    public static final List<xxxx> ALL_TYPE = new ArrayList<>();

    static {
        //功能授权
        ALL_TYPE.addAll(Arrays.asList(MAN, FEMALE));
    }
}

使用 enum

import static com.xxxx.common.HumanTypeEnum.*;

@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {
	ALL_TYPE.forEach(info -> xxxx)
}

带有构造方法的枚举 带有抽象方法的枚举

enum 关键字定义的枚举类都默认继承了Enum 类(抽象类)、该类位于 java.lang下、该类具有两个 final 常量:

name :枚举常量,如上例中的 SUN MON 等
ordinal :类似数组索引,即位置(position)的意思,默认值从0开始

下为Enum类的部分源码:

public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {

    // The name of this enum constant, as declared in the enum declaration.
    private final String name;

    public final String name() {
        return name;
    }
    
    public String toString() {
        return name;
    }
    
    /**
     * The ordinal of this enumeration constant (its position in the enum declaration, 
     * where the initial constant is assigned an ordinal of zero).
     */
    private final int ordinal;

    public final int ordinal() {
        return ordinal;
    }

    // Sole constructor.  Programmers cannot invoke this constructor.
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
   
    public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }
}

实现带有构造方法的枚举(项目中常使用的方式)

public enum Sex {
    MALE(1, "男"),
    FEMALE(2, "女");

    public final Integer type;
    public final  String value;

    private Sex(Integer type, String value){
        this.type = type;
        this.value = value;
    }
}
public class SexEnumTest {
    public static void main(String[] args) {
        Sex man = Sex.MALE;

        System.out.println(man);            // MALE  调用默认的toString()
        System.out.println(man.name());     // MALE
        System.out.println(man.ordinal());  // 0

        System.out.println(man.type);       // 1
        System.out.println(man.value);      // 男
    }
}

抽象方法

带有抽象方法的枚举、在上例的基础上添加一个抽象方法

public enum Sex {
    MALE(1, "男"){
        @Override
        public void haircut() {
            System.out.println("剃个光头吧~");
        }
    },
    FEMALE(2, "女"){
        @Override
        public void haircut() {
            System.out.println("还是留长发吧~");
        }
    };

    public final Integer type;
    public final  String value;

    private Sex(Integer type, String value){
        this.type = type;
        this.value = value;
    }

    public abstract void haircut();
}
public class SexEnumTest {
    public static void main(String[] args) {
        Sex man = Sex.MALE;

        System.out.println(man);            // MALE  调用默认的toString()
        System.out.println(man.name());     // MALE
        System.out.println(man.ordinal());  // 0

        System.out.println(man.type);       // 1
        System.out.println(man.value);      // 男

        man.haircut();                      // 剃个光头吧~
        Sex.FEMALE.haircut();               // 还是留长发吧~
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值