1.常量

在JDK1.5 之前,我们常见的定义常量都是: public static fianl…。现在有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。而且枚举类型可以帮助我们检测许多的编译失误,使用枚举,也能让我们的代码可读性更强
例子:

public enum People {
    MAN,WOMAN
}

测试:

public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
    }
输出:
MAN
WOMAN
MAN

2.向枚举中添加新方法

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例,且枚举类型的构造方法必须为私有方法。枚举类型中可以有静态方法,也可以与其他方法。可以有属性与get,set方法
例子:

public enum People {
    MAN(10,"bb"),WOMAN(20,"gg");//这里必须要有分号,属性可以自定义多个
    private int year;
    private String name;

    private People(int year, String name) {//这个构造方法必须是私有的
        this.year = year;
        this.name = name;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public  int getYears(String name){//自定义方法获取年龄
        for(People p:values()){
            if(p.getNames().equals(name)){
                return p.getYear();
            }
        }
        return 0;
    }
}

测试:

public class TestEnum {
    public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
        //得到里面具体的属性
        System.out.println(People.MAN.getNames()+","+People.MAN.getYear());
        //使用自定义方法
        System.out.println(People.MAN.getYears("bb"));
    }
}

输出:

MAN
WOMAN
MAN
bb,10
10

项目中常见用法

public class Constant {
	/** 超级管理员ID */
	public static final int SUPER_ADMIN = 1;
	//菜单类型
	public enum MenuType {
	        /**
	         * 目录
	         */
	    	CATALOG(0),
	        /**
	         * 菜单
	         */
	        MENU(1),
	        /**
	         * 按钮
	         */
	        BUTTON(2);
	
	        private int value;
	
	        MenuType(int value) {
	            this.value = value;
	        }
	
	        public int getValue() {
	            return value;
	        }
	    }
  }

调用枚举
Constant.MenuType.CATALOG.getValue()

3.覆盖枚举的方法

public enum People {
    MAN(10,"bb"),WOMAN(20,"gg");
    private int year;
    private String names;

    private People(int year, String names) {
        this.year = year;
        this.names = names;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public String getNames() {
        return names;
    }

    public void setNames(String names) {
        this.names = names;
    }
    public  int getYears(String name){
        for(People p:values()){
            if(p.getNames().equals(name)){
                return p.getYear();
            }
        }
        return 0;
    }

    @Override
    public String toString() {
        return "{" +
                "year=" + year +
                ", names='" + names + '\'' +
                '}';
    }
}

测试:

public class TestEnum {
    public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
        //得到里面具体的属性
        System.out.println(People.MAN.getNames()+","+People.MAN.getYear());
        //使用自定义方法
        System.out.println(People.MAN.getYears("bb"));
    }
}

输出:

{year=10, names='bb'}
{year=20, names='gg'}
{year=10, names='bb'}
bb,10
10

4.switch

测试

public class TestEnum {
    public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
        //得到里面具体的属性
        System.out.println(People.MAN.getNames()+","+People.MAN.getYear());
        //使用自定义方法
        System.out.println(People.MAN.getYears("bb"));
        //使用实现接口方法
        System.out.println(People.MAN.getYearByInterface());
        //
        int year=People.MAN.getYear();
        switch (year) {
            case 10:
                System.out.println("bb");
                break;
            case 20:
                System.out.println("gg");
                break;
            default:
                break;
        }
    }
}

输出

{year=10, names='bb'}
{year=20, names='gg'}
{year=10, names='bb'}
bb,10
10
10
bb

5.用抽象方法+枚举内部类

例子

public enum People implements getYearByInterface{
    MAN(10,"bb"){
        @Override//@Override需要有,没有会报错
        public String oldName(){
            return "cc";
        }
    },WOMAN(20,"gg"){
        @Override
        public String oldName(){
            return "dd";
        }
    };
    private int year;
    private String names;
    public abstract String oldName();//抽象方法需要加上
    private People(int year, String names) {
        this.year = year;
        this.names = names;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public String getNames() {
        return names;
    }

    public void setNames(String names) {
        this.names = names;
    }
    public  int getYears(String name){
        for(People p:values()){
            if(p.getNames().equals(name)){
                return p.getYear();
            }
        }
        return 0;
    }

    @Override
    public String toString() {
        return "{" +
                "year=" + year +
                ", names='" + names + '\'' +
                '}';
    }

    @Override
    public int getYearByInterface() {
        return this.getYear();
    }
}

测试

public class TestEnum {
    public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
        //得到里面具体的属性
        System.out.println(People.MAN.getNames()+","+People.MAN.getYear());
        //使用自定义方法
        System.out.println(People.MAN.getYears("bb"));
              //switch
        int year=People.MAN.getYear();
        switch (year) {
            case 10:
                System.out.println("bb");
                break;
            case 20:
                System.out.println("gg");
                break;
            default:
                break;
        }
        //每一个enum枚举值还可以拥有各自的内部方法
        System.out.println(People.MAN.oldName());
       
    }
}

输出

{year=10, names='bb'}
{year=20, names='gg'}
{year=10, names='bb'}
bb,10
10
bb
cc

6.原理

后面的用法要知道枚举类的原理,可以利用javap反汇编查看编译好的class文件,我们使用enum定义的枚举类型,会在编译之后转化为一个继承了java.lang.Enum的类,并且声明为final,其内部维护多个实例,而且是在静态代码块中进行实例化多个实例,我们定义的每个枚举值都会在类的初始化阶段被实例化为我们所定义的枚举类的一个对象。同时,编译器还帮我们在类中增加了两个方法,分别是:values()和valueOf()。

7.实现接口

前面的原理说过枚举类编译之后都会去继承java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类,但是可以实现接口,来增加方法
接口

public interface GetYearByInterface {
    public int getYearByInterface();
}

例子

public enum People implements getYearByInterface{
    MAN(10,"bb"),WOMAN(20,"gg");
    private int year;
    private String names;

    private People(int year, String names) {
        this.year = year;
        this.names = names;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public String getNames() {
        return names;
    }

    public void setNames(String names) {
        this.names = names;
    }
    public  int getYears(String name){
        for(People p:values()){
            if(p.getNames().equals(name)){
                return p.getYear();
            }
        }
        return 0;
    }

    @Override
    public String toString() {
        return "{" +
                "year=" + year +
                ", names='" + names + '\'' +
                '}';
    }

    @Override
    public int getYearByInterface() {
        return this.getYear();
    }
}

测试

public class TestEnum {
    public static void main(String[] args){
        //循环Enum自带的values(),可以获取该枚举类型里的所有常量
        for(People p:People.values()){
            System.out.println(p);
        }
        //直接输出某一个常量
        System.out.println(People.MAN);
        //得到里面具体的属性
        System.out.println(People.MAN.getNames()+","+People.MAN.getYear());
        //使用自定义方法
        System.out.println(People.MAN.getYears("bb"));
        //使用实现接口方法
        System.out.println(People.MAN.getYearByInterface());
    }
}

输出

{year=10, names='bb'}
{year=20, names='gg'}
{year=10, names='bb'}
bb,10
10
10

8.使用接口组织枚举

接口

public interface Color {
    enum red implements Color{
        red1,red2,red3
    }
    enum blue implements Color{
        blue1,blue2,blue3
    }
}

测试

public class TestEnum {
    public static void main(String[] args){
        //搞个实现接口,来组织枚举,简单讲,类似分类吧。如果大量使用枚举的话,会方便调用了
        Color color=Color.red.red1;
        System.out.println(color);
        color=Color.blue.blue1;
        System.out.println(color);
    }
}

输出

red1
blue1

9.关于枚举集合的使用

java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。enumSet继承AbstractSet,AbstractSet实现了set接口。EnumMap继承AbstractMap,AbstractMap继承实现map接口。而且EnumMap中的中key必须为枚举类型,而且不能为null

10.Enum抽象类常见方法

Enum是所有 Java 语言枚举类型的公共基本类(注意Enum是抽象类),以下是它的常见方法:

java 枚举默认值 java枚举类型enum用法_System