1.枚举的定义

枚举是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁,安全性以及便捷性。创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类(java.lang.Enum是一个抽象类)。枚举类型符合通用模式Class Enum>,而E表示枚举类型的名称。枚举类型的每一个值都映射到protected Enum(String name,int ordinal)构造函数中,在这里,每个值的名称都转换成一个字符串,并且序数设置表示了此设置被创建的顺序。(这段完整的从一个培训机构官网抄的)

2.枚举的简单使用

package test_2021_1_5.枚举;

/**
 * 枚举的简单使用
 */
 enum demo01 {
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,WEEKEND;
}



public class test {
    public static void main(String[] args) {
        System.out.println(demo01.MONDAY);
    }
}

3.枚举的原理

 

将枚举类的class文件进行反编译得到下面这个文件,我们可以看到demo01这个类继承了Enum这个类,也就是说编译器在编译这个枚举类型的类的时候将我们的java文件修改成了这样,然后在变成字节码文件

package test_2021_1_5.679A4E3E;
final class demo01 extends Enum
{
    public static demo01[] values()
    {
        return (demo01[])$VALUES.clone();
    }
    public static demo01 valueOf(String name)
    {
        return (demo01)Enum.valueOf(test_2021_1_5/679A4E3E/demo01, name);
    }
    private demo01(String s, int i)
    {
        super(s, i);
    }
    public static final demo01 MONDAY;
    public static final demo01 TUESDAY;
    public static final demo01 WEDNESDAY;
    public static final demo01 THURSDAY;
    public static final demo01 FRIDAY;
    public static final demo01 SATURDAY;
    public static final demo01 WEEKEND;
    private static final demo01 $VALUES[];
    static 
    {
        MONDAY = new demo01("MONDAY", 0);
        TUESDAY = new demo01("TUESDAY", 1);
        WEDNESDAY = new demo01("WEDNESDAY", 2);
        THURSDAY = new demo01("THURSDAY", 3);
        FRIDAY = new demo01("FRIDAY", 4);
        SATURDAY = new demo01("SATURDAY", 5);
        WEEKEND = new demo01("WEEKEND", 6);
        $VALUES = (new demo01[] {
            MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, WEEKEND });
    }}

我们分析下这个被修改的后的类,这是我大概做的一张图,顺序由上往下看就好,首先它继承了Enum这个类,这是个抽象的类,等会再说这个父类,先说这个枚举类,在被修改之后,变成了一个普通的类,并且为这个类添加了两个静态的普通方法,和构造函数,以及一个数组,这个类的名字和之前定义的枚举类型的名字一样,定义的所有枚举类型demo01中的变量全都变成了普通类demo01中被final,static修饰的常量实例,并且在这里也进行了实例化,以声明的名字为标识符,声明时所处于的位置为它的位置编号,最后把这些实例按顺序声明时的顺序添加进了数组,这就是整个过程,从枚举类型----》普通类型

java 根据数据库类型动态获取枚举 java 枚举 数据库_枚举类型

4.Enum类中方法

然后看一下它的父类Enum,这是它里面的一些方法,

java 根据数据库类型动态获取枚举 java 枚举 数据库_枚举类型_02

这里面的的方法很多都是final类型的,Enum是个抽象类,所以我们创建的类都继承了这些方法,其中toString方法和name()方法的作用是一样的,oridinal方法返回的是你声明的顺序,如果你在声明这个枚举类型变量的顺序改变了获取的值也会改变,官方文档中告诉我们,通常不会使用这个方法,一般被设计为使用复杂的基于枚举的数据结构,如EnumSet和EnuMap,之后再来探讨这两个东西,然后我们对上述的方法进行简单的使用,测试一下
 

java 根据数据库类型动态获取枚举 java 枚举 数据库_枚举类_03

这里我说一个东西,Enum类中valueOf方法是一个静态方法,所以不能被我们定义的枚举类型继承,反编译后的java类中出现的values方法和valueOf方法都是编译器给添加的,不就是继承而来,假如说向上转型后,那么就没办法使用values方法,但是可以获取class对象,并且通过Class类中的isEnum方法和getEnumConstants()方法得到那个数组

java 根据数据库类型动态获取枚举 java 枚举 数据库_枚举类型_04

到这里枚举的简单使用和原理基本就介绍完了,接下里就介绍下枚举类型的深入使用

5.深入枚举

      在枚举类中定义构造方法和成员变量

public  enum  demo02{
    boy("男"),
    girl("女");
    private String name;
    demo02(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}

          在枚举类中定义抽象方法,每个枚举类型变量可以做不同的事

public  enum  demo02{
    boy("男") {
        @Override
        void everyOneMethod() {
            System.out.println("站着袅袅");
        }
    },
    girl("女") {
        @Override
        void everyOneMethod() {
            System.out.println("蹲着袅袅");
        }
    };
    private String name;
    demo02(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
 abstract void  everyOneMethod();
}

          在枚举类中添加main方法

public  enum  demo02{
    boy("男") {
        @Override
        void everyOneMethod() {
            System.out.println("站着袅袅");
        }
    },
    girl("女") {
        @Override
        void everyOneMethod() {
            System.out.println("蹲着袅袅");
        }
    };
    private String name;
    demo02(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
 abstract void  everyOneMethod();

    public static void main(String[] args) {
        demo02.boy.everyOneMethod();
        demo02.girl.everyOneMethod();
    }
}

              可以重写父类中没有被final修饰并且不是静态的,并且不是私有的方法,实际上只有一个toString方法

public  enum  demo02{
    //public int id;  枚举类型变量的声明在最前面
    boy("男") {
        @Override
        void everyOneMethod() {
            System.out.println("站着袅袅");
        }
    },
    girl("女") {
        @Override
        void everyOneMethod() {
            System.out.println("蹲着袅袅");
        }
    };
    private String name;
    demo02(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
 abstract void  everyOneMethod();

    @Override
    public String toString() {
        System.out.println("你是憨蛋吗");
        String string = super.toString();
        return string;
    }

    public static void main(String[] args) {
        demo02.boy.everyOneMethod();//站着袅袅
        demo02.girl.everyOneMethod();//蹲着袅袅
        String string = demo02.boy.toString();//你是憨蛋吗
        System.out.println(string);//boy
        String string1 = demo02.girl.toString();//你是憨蛋吗
        System.out.println(string1);//girl
    }
}

   枚举实现接口,有两种表示方法

   Happy接口

public interface Happy {
    public abstract void talkDream();

}

     第一种,大家表达的内容一致

enum demo01 implements Happy{
    MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,WEEKEND;
    @Override
    public void talkDream() {
        System.out.println("大家都是一样的");
    }
}

     第二种,各自有各自的想法

enum demo01 implements Happy {
    MONDAY {
        @Override
        public void talkDream() {

        }
    }, TUESDAY {
        @Override
        public void talkDream() {

        }
    }, WEDNESDAY {
        @Override
        public void talkDream() {

        }
    }, THURSDAY {
        @Override
        public void talkDream() {

        }
    }, FRIDAY {
        @Override
        public void talkDream() {

        }
    }, SATURDAY {
        @Override
        public void talkDream() {

        }
    }, WEEKEND {
        @Override
        public void talkDream() {

        }
    };
}

 

此外还有枚举的单例模式,这个我打算分开写,与其他的单例一起进行分析,不在这写,还有EnumMap和EnumSet,暂时没有太多理解,以后补充吧