Java#枚举

知识点

在这里插入图片描述

背景

1、案例引申

一些程序在运行时要求数据不能是任意的,必须是一定范围内的值。jdk5 以前采用自定义类常量来解决,而jdk5 以后出现了枚举。

假如有成绩A B C D E。 JDK5以前会以下面的方式定义

class Grade{
    private Grade(){}//1 私有构造
    // 2 规定只能访问特定的值
    public static final Grade A=new Grade();
    public static final Grade B=new Grade();
    public static final Grade C=new Grade();
    public static final Grade D=new Grade();
    public static final Grade E=new Grade();

}

   //测试类中才能达到使用特定的值
  public static void main(String[] args){
        // 测试类中使用值通过这种方式访问
         System.out.println(Grade.A);
         System.out.println(Grade.B);
         ...
    }

JDK5以后会以以下面的方式定义

enum Grade{
    A ,B,C,D,E;
}
 public static void main(String[] args){
        // 测试类中使用值通过这种方式访问
         System.out.println(Grade.A);
         System.out.println(Grade.B);
         ...
    }

对比发现,写代码时少了很多语句声明,舒服多啦~

枚举

1、枚举的构造

如上的案例引申,直接定义了A、B、C、D、E 5个枚举常量对象。其实枚举类和普通类一样,默认也是无参构造,这里进行代码修改,添加带参数的构造。

enum Grade{
    A("100-99") ,B("99-80"),C("80-70"),D("70-60");
    private String value; //定义个类的成员
    Grade(String value){//构造
        this.value=value;
    }
    public String getValue(){
        return value;
    }
}
  
  //测试
   public static void main(String[] args){
        //简单的对象调用方法
        System.out.println(Grade.A.getValue());
}

总结:

  • 枚举中的构造必须为私有(private)或者不写(默认为private )
    原因:构造方法为private目的就是为了不让你用new来创建该类型的对象,而枚举类型的个数必须是确定的(根据枚举体的作用定义)所以它必须是private
  • 枚举的成员是可以有的,和普通的成员一样定义使用。
  • 枚举的方法可以有的,和普通的方法一样定义使用。
    注意:定义枚举类实成员命名规范,一般按照常量的书写形式-大写。

ps:枚举成员为什么不能是数字?
变量的命名规范规定变量只能以$、_、和字母开头开头的

2 、枚举类的成员

两类:
1、枚举类实例
定义方式相当于我们定义普通变量方式(int a,b,c;)只不过定义的时候枚举类实例就完成了初始化。
2、普通定义的成员
定义方式和我们在普通类中定义成员一样,使用方式也一样。

3、带抽象方法的枚举类
enum Grade{
    
    A("100-99") ,B("99-80"),C("80-70"),D("70-60");
    private String value;
     Grade(String value){
        this.value=value;
    }
    public String getValue(){
        return value;
    }
    public String getGrade(){
         return "优秀";
    }
}

上面的 getGrade方法,如果在测试类中使用 Grade.A.getGrade(),A换为B,C…我们得到的都是“优秀”,如下改善添加抽象方法:

enum Grade{

    // A 代表的就是枚举对象,所以必须实现类中定义的抽象方法
    A("100-99"){
        @Override
        public String getGrade() {
            return "优秀";
        }
    } ,
    B("99-80") {
        @Override
        public String getGrade() {
            return "良好";
        }
    },
    C("80-70") {
        @Override
        public String getGrade() {
            return "及格";
        }
    },
    D("70-60") {
        @Override
        public String getGrade() {
            return "不及格";
        }
    };
    private String value;
     Grade(String value){
        this.value=value;
    }
    public String getValue(){
        return value;
    }
    // 抽象方法
    public abstract String getGrade();
}

4 、枚举特有的方法

这里参看官方文档最合适不过了。emmmmm~

image.png

常用的:

  • name()返回枚举类的常量值,和直接打印类名.枚举值一样(toString方法已经实现)
  • ordinal ()返回枚举的索引序数,遍历枚举值会用到
  • toString()枚举类已经重写,直接返回实例的字符串形式。(看看name方法和toString的作用差不多)
5、实现接口和继承问题

(1)接口的实现

和普通类实现接口一样

(2)继承问题

所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

Enum类源码:

/**
 * This is the common base class of all Java language enumeration types.  这是所有枚举的基类
 * @param <E> The enum type subclass
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Class#getEnumConstants()
 * @see     java.util.EnumSet   枚举set 参看java提供的枚举set集合
 * @see     java.util.EnumMap  枚举map  参看java提供的枚举map集合
 * @since   1.5   java 1.5添加枚举
 */
public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
       ...
       ...
       }

枚举的应用

1、枚举的单例:
/**
 * Created by sunnyDay on 2019/7/22 16:13
 */
class Singleton{
    //私有构造
    private Singleton() {
    }
    
    // 通过枚举提供单例
    enum SomeThing {
        INSTANCE;
        private Singleton singleton;

        SomeThing() { //枚举的构造默认就是私有
            singleton = new Singleton();
        }

        public Singleton getSingleton() {
            return singleton;
        }
}

  public static void main(String[] args) {
        System.out.println(SomeThing.INSTANCE.getSingleton());
        System.out.println(SomeThing.INSTANCE.getSingleton());
        System.out.println(SomeThing.INSTANCE.getSingleton());
         // log:
         //javapck.Singleton@330bedb4
         //javapck.Singleton@330bedb4
         //javapck.Singleton@330bedb4
 }
 
}

首先,在枚举中明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。 也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。更多单利参考:单例设计模式(Singleton)

2、枚举应用于switch语句
/**
 * Created by sunnyDay on 2019/7/22 16:37
 */
public class Test {
    public void testEnum(Grade grade) {
        switch (grade) {
            case A: //注意此处Grade.A 会报错
                System.out.println("优秀");
                break;
            case B:
                System.out.println("良好");
                break;
            default:
        }
    }
}

public enum Grade {
    A,B
}

小结

  • 枚举类是一种特殊的java类
  • 枚举类中声明的每一个枚举值代表一个枚举类的实例对象
  • 与java的普通类一样,在声明枚举类时也可以声明属性、方法,构造函数,但是构造函数必须为私有(原因参上有解释)
  • 枚举类也可以实现接口。不能继承其他类。
  • jdk5中扩展了switch语句,除了可以接受int byte char short(没有long)外,还可以接受枚举类型,
  • 枚举若只有一个值则可以当做单利设计模式使用

end

参考文章:

Java 枚举(enum) 详解7种常见的用法

如何在switch中使用enum,你真的知道吗?

Java中switch都可以支持哪些数据类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值