Java枚举

Enum

Posted by Static on June 28, 2018

1. 什么实枚举?

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。


2. Java枚举内幕

通过下面Car.java文件及Car.class文件,大概就明白枚举是啥玩意了

Car.java

package com.github.whvixd.demo.enumDemo;

/**
 * Created by wangzhx on 2018/6/28.
 */
public enum Car {
    LAMBORGHINI,KOENIGSEGG
}

com.github.whvixd.Car.class;

$ javap Car.class
Compiled from "Car.java"
public final class Car extends java.lang.Enum<Car> {
  public static final Car LAMBORGHINI;
  public static final Car KOENIGSEGG;
  public static Car[] values();
  public static Car valueOf(java.lang.String);
  static {};
}

为什么Enum中定义元素都是大写->这是规范!

枚举元素的修饰符:public static final,如下

package com.github.whvixd;

import com.github.whvixd.demo.enumDemo.Car;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * Created by wangzhx on 2018/6/28.
 */
public class TestEnum {

    @Test
    public void test() {
        Class kClazz = Car.KOENIGSEGG.getClass();
        Field[] fields = kClazz.getFields();
        //遍历Car类的元素
        for (Field field : fields) {
            //判断元素的修饰符
            if (Modifier.isPublic(field.getModifiers()) &&
                    Modifier.isStatic(field.getModifiers()) &&
                    Modifier.isFinal(field.getModifiers())) {
                System.out.println(field.getName() + "元素的修饰符为 public static final");
            }
        }
    }
}

/*
LAMBORGHINI元素的修饰符为 public static final
KOENIGSEGG元素的修饰符为 public static final
*/

知道枚举为什么是单例了吧

3. Java枚举的用法

1. 我们可以利用枚举写出优雅的代码

package com.github.whvixd.demo.enumDemo;

import lombok.Getter;
import lombok.Setter;

/**
 * Created by wangzhx on 2018/6/28.
 */
public enum Car {
    LAMBORGHINI("兰博基尼", 3E8), KOENIGSEGG("科尼赛克", 1E9);

    @Setter
    @Getter
    private String carBrand;

    @Setter
    @Getter
    private double price;

    Car(String carBrand, double price) {
        this.carBrand = carBrand;
        this.price = price;
    }

}

上面的代码与下面代码类似

package com.github.whvixd.demo.enumDemo;

import lombok.Getter;
import lombok.Setter;

/**
 * Created by wangzhx on 2018/6/28.
 */
public class Car{
    public static final Car LAMBORGHINI = new ICar("兰博基尼",3E8);
    public static final Car KOENIGSEGG = new ICar("科尼赛克",1E9);

    @Setter
    @Getter
    private String carBrand;

    @Setter
    @Getter
    private double price;

    Car(String carBrand, double price) {
        this.carBrand = carBrand;
        this.price = price;
    }

}

2. 利用枚举写一个工厂模式

package com.github.whvixd.demo.enumDemo;

import lombok.Getter;
import lombok.Setter;

/**
 * Created by wangzhx on 2018/6/28.
 */
public interface Factory {
    enum Car{
        LAMBORGHINI("兰博基尼", 3E8), KOENIGSEGG("科尼赛克", 1E9);

        @Setter
        @Getter
        private String carBrand;

        @Setter
        @Getter
        private double price;

        Car(String carBrand, double price) {
            this.carBrand = carBrand;
            this.price = price;
        }
    }

    interface ICar{
        String printCarName(Car car);
    }

    //实现ICar接口
    enum ICarImpl implements ICar{
        LAMBORGHINI{
            @Override
            public String printCarName(Car car) {
                //根据入参不同去写对应的逻辑
                if("兰博基尼".equals(car.getCarBrand())){
                    return "兰博基尼";
                }
                return "";
            }
        },KOENIGSEGG {
            @Override
            public String printCarName(Car car) {
                //根据入参不同去写对应的逻辑
                if(1E9 == car.getPrice()){
                    return car.getCarBrand()+"价格:"+car.getPrice();
                }
                return null;
            }
        }
    }

}

测试

package com.github.whvixd;

import com.github.whvixd.demo.enumDemo.Car;

import com.github.whvixd.demo.enumDemo.Factory;
import org.junit.Assert;
import org.junit.Test;

/**
 * Created by wangzhx on 2018/6/28.
 */
public class TestEnum {

    @Test
    public void testFactory() {
        //创建入参创建对应的实例
        Factory.ICar iCar = Factory.ICarImpl.valueOf(Car.KOENIGSEGG.name());

        //用KOENIGSEGG这个对象去调用printCarName方法
        Assert.assertSame("科尼赛克价格:1E9",
                iCar.printCatName(Factory.Car.KOENIGSEGG));
    }
}