Java 枚举enum类

Java枚举(Enum)

枚举

定义:

  • Java枚举是一种特殊的类,用来表示一组固定的常量。

  • 被enum关键字修饰的类型就是枚举类型

    (如果枚举不添加任何方法,枚举值默认为从0开始的有序数据。

比如定义一个枚举类表示季节,那里面有春、夏、秋和冬四个变量。

一个枚举类表示星期,那里面有星期一、星期二、星期三、星期四、星期五、星期六和星期日七个变量

枚举类表示月份就同理有十二个月、十二个变量。

  • 格式:

    • Java 枚举类使用 enum 关键字来定义,enum关键字的作用就像是classinterface
    • 各个常量使用逗号 , 来分割。注意最后一个枚举对象要使用“;”结尾,说明枚举值结束使用。
  • 1 枚举的本质:其实就是终止类,并继承Enum抽象类。

    2 枚举中的变量,其实就是一个当前类型的静态常量。

  • 枚举类型本质上是java.lang.Enum类的子类,(java.lang.Enum是一个抽象类)但Java中不支持多继承,因此枚举类型不能再继承其他类。

//测试类
public enum Season {       //上文说的季节类
    //每个成员变量都默认被 public final static修饰
    SPRING, SUMMER, AUTUMN, WINTER;
}
//测试类
public class SeasonTest {
    public static void main(String[] args) {
        for (Season seasonEnum : Season.values()) {
            System.out.println(seasonEnum+",ordinal:"+seasonEnum.ordinal()+",name:"+seasonEnum.name());
        }
    }
}
  • 每个被枚举的成员其实就是定义的枚举类型的一个实例,它们都被默认为final。无法改变常数名称所设定的值,它们也是public和static的成员,这与接口中的常量限制相同。可以通过类名称直接使用它们。

枚举中的方法

  • values() :返回enum实例的数组,而且该数组中的元素严格保持在enum中的声明时的顺序。

  • name():返回实例名。

  • ordinal():返回实例声明时的次序,从0开始

  • getDeclaringClass():返回实例所属的enum类型。

  • equals():判断是否为同一个对象

    也可以使用"=="来比较enum实例

  • valueOf():返回指定字符串值的枚举常量。

特性

  1. 除了不能继承,可以将enum看作一个普通类。
  2. Java不允许使用=为枚举常量赋值。
  3. enum通过方法来显式赋值
  4. enum可以添加普通方法、静态方法、抽象方法、构造方法。
  5. 枚举可以实现接口
  6. 枚举不可以继承

枚举类中定义抽象方法

既然编译器最终将每个枚举值声明为枚举类的实例,那我们能在枚举类中声明抽象方法让枚举值去实现么?

在枚举类Season中声明了一个抽象方法sayHello()。然后在创建枚举值时,就必须实现该抽象方法

public enum SeasonEnum {
    //枚举类的实例对象必须在最前面先定义,而且必须每个实例对象都必须维护上chinese成员变量
    SPRING("春天",1201){
        @Override
        void sayHello() {
            System.out.println("hello spring");
        }
    },
    SUMMER("夏天",1202){
        @Override
        void sayHello() {
            System.out.println("hello summer");
        }
    },
    AUTUMN("秋天",1203){
        @Override
        void sayHello() {
            System.out.println("hello autumn");
        }
    },
    WINTER("冬天",1204){
        @Override
        void sayHello() {
            System.out.println("hello winter");
        }
    };

    private String name;
    private Integer code;

    //枚举类型的构造函数默认为private,因为枚举类型的初始化要在当前枚举类中完成。
    SeasonEnum (String name,Integer code){
        this.name=name;
        this.code=code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    abstract void sayHello();
}

测试类:

public class SeasonTest {
    public static void main(String[] args) {
        //直接初始化
        SeasonEnum season1 = SeasonEnum.SPRING;
        //调用SeasonEnum枚举类的sayHello方法
        season1.sayHello();
    }
}

控制台输出:

hello spring
  1. 枚举允许继承类吗?

    枚举类使用enum定义后在编译后默认继承了java.lang.Enum类,而不是普通的继承Object类。enum声明类继承了Serializable和Comparable两个接口。且采用enum声明后,该类会被编译器加上final声明(同String),故该类是无法继承的。

    所有枚举类都默认是Enum类的子类,无需我们使用extends来继承。

    1. 枚举允许实现接口吗?

    枚举允许实现接口。因为枚举本身就是一个类,类是可以实现多个接口的。

    public interface EnumInterface {
        public abstract void print();
    }
    public enum SizeEnum implements EnumInterface{
        BIG,MIDDLE,SMALL;
    
        @Override
        public void print() {
            System.out.println("继承接口-重写方法一次");
        }
    }
    
    1. 枚举可以用等号比较吗?

    肯定,因为在Enum类里面,已经重写了equals方法,而方法里面比较就是直接使用==,来比较2个对象的。所以,你在外边直接使用==也是可以的。

    Java 枚举enum类_第1张图片

    1. 可以继承枚举吗?

    当然不能呀,枚举类默认继承了java.lang.Enum类,一个类怎么能继承两个类呢?

    1. 枚举可以实现单例模式吗?

    枚举本身就是一种对单例设计模式友好的形式,它是实现单例模式的一种很好的方式。

    public class InstanceDemo {
    
        /**
         * 构造方法私有化
         */
        private InstanceDemo(){
    
        }
    
        /**
         * 返回实例
         * @return
         */
        public static InstanceDemo getInstance() {
            return Singleton.INSTANCE.getInstance();
        }
    
        /**
         * 使用枚举方法实现单利模式
         */
        private enum Singleton {
            INSTANCE;
    
            private InstanceDemo instance;
    
            /**
             * JVM保证这个方法绝对只调用一次
             */
            Singleton() {
                instance = new InstanceDemo();
            }
    
            public InstanceDemo getInstance() {
                return instance;
            }
        }
    
    //测试一下
        public static void main(String[] args) {
            InstanceDemo one =  InstanceDemo.getInstance();
            InstanceDemo two =  InstanceDemo.getInstance();
            System.out.println(one);
            System.out.println(two);
            System.out.println(one == two);
        }
    }
    

    创建的对象相同

    csdn.test.recursion.demo.InstanceDemo@74a14482
    csdn.test.recursion.demo.InstanceDemo@74a14482
    true
    
    1. 当使用compareTo()比较枚举时,比较的是什么?

    int compareTo(E e):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序;返回值可以仔细看看源码;

    一起看看,底层代码吧

     public final int compareTo(E o) {
            Enum other = (Enum)o;
            Enum self = this;
            if (self.getClass() != other.getClass() && // optimization
                self.getDeclaringClass() != other.getDeclaringClass())
                throw new ClassCastException();
            return self.ordinal - other.ordinal;
        }
    

    举个例子你就能理解了

    public class TestSeasonEnum {
        public static void main(String[] args) {
        
            Season season = Season.SPRING;
            Season season1 = Season.SUMMER;
            Season season2 = Season.AUTUMN;
            Season season3 = Season.WINTER;
    
            System.out.println(season.compareTo(season1));
            System.out.println(season.compareTo(season2));
            System.out.println(season.compareTo(season3));
        }
    }
    

    输出结课,详情参考源码一看便知道

    -1
    -2
    -3

    1. 当使用equals()比较枚举的时候,比较的是什么?

    枚举类型的equals()方法比较的是枚举类对象的内存地址,作用与等号等价。

你可能感兴趣的:(Java语言基础,java,python,开发语言,职场和发展)