枚举(Enumeration)

枚举

 在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。正好是可以通过枚举来使用这些数据集。

  1. 定义枚举类型:使用关键字enum
  • 源代码:
public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
    /**
     * The name of this enum constant, as declared in the enum declaration.
     * Most programmers should use the {@link #toString} method rather than
     * accessing this field.
     */
    private final String name;
    }
  • 声明枚举其实就是定义一种特殊形式的类,但不能通过关键字new创建其对象实例。 因为自定义的枚举,都是继承 Enum 类构造函数默认为私有的。
  • 枚举成员默认都是public static final 的,即常量。按命名规则,枚举类中的枚举值全部大写,任意两个枚举值不能具有相同的名称。
  • 在枚举声明中,只允许pubic,不允许abstract和final修饰符。枚举不能是抽象的,也不允许派生。
//定义一个枚举类
enum  Color{
    RED,GREEN,WHITE,BLACK;      //(分号可有可无) 定义对象,枚举的实例是常量
}
  1. 常用的枚举类型的方法:
  • 所有的枚举类型均隐式地继承于Enum类(java.lang.Enum),故所有的枚举类型都继承了Enum类的方法。声明枚举类型时,编译器会自动提供相应方法的实现。
  • 常见方法:
    在这里插入图片描述
enum  Color {
    RED,GREEN,WHITE,BLACK;      //(分号可有可无) 定义对象  枚举的实例是常量
}

public class Enum {
    public static void main(String[] args) {
        Color color = Color.BLACK; //直接引用
        Color color2 = Color.GREEN;

        System.out.println(color.ordinal());   //某个特定的枚举常量的声明顺序,返回枚举常量的序数
                                             // (它在枚举声明中的位置,其中初始常量序数为零)
        System.out.println("======");
        System.out.println(color.toString());   //返回name 实例的名字
        System.out.println("======");
        System.out.println(color.name());  //返回name
        System.out.println("======");
        System.out.println(Color.valueOf("BLACK"));//(String name) 返回name // 返回带指定名称的指定枚举类型的枚举常量。
        System.out.println("======");
        System.out.println(color.equals(color2)); //枚举类型的比较 boolean 类型
        System.out.println("======");
        System.out.println(color == color2);  //boolean 类型
        System.out.println("======");
        System.out.println(color.compareTo(color2));   //比较此枚举与指定对象的顺序
        System.out.println("======");
        System.out.println(color.getDeclaringClass());  //返回与此枚举常量的枚举类型相对应的 Class 对象
        //values 把枚举的实例,都变成一个数组,这个过程是由编译器生成的  static方法
        System.out.println("======");
        for (Color c:Color.values()){
            System.out.println(c);
        }
      
	}
}
//output:
3
======
BLACK
======
BLACK
======
BLACK
======
false
======
false
======
2
======
class com.k.Color
======
RED
GREEN
WHITE
BLACK
  • 枚举值可用于switch…case语句。
 Color color3 = Color.WHITE;  //类名访问
        //JDK 1.5 后支持,作为switch 参数
        switch (color3){
            case RED:
                System.out.println("red");
                break;
            case BLACK:
                System.out.println("black");
                break;
            case GREEN:
                System.out.println("green");
                break;
            case WHITE:
                System.out.println("white");
                break;
        }
//output:
white
  1. 声明枚举类型的其他成员方法:
  • 在枚举类型中,除了声明枚举值之外,还可以声明其他类成员,包括构造方法、方法和数据成员。
    注意:枚举类的构造方法与一般类的构造方法不同,枚举类构造方法的访问修饰符只能为private(声明时可以省略private,因为默认为private),构造方法只是在构造枚举值的时候被调用。
public enum TestEnum {

    RED("red",1),BLACK("black", 2),GREEN("green", 3),WHITE("white", 4);//传参数

    private String name;
    private  int key;
    //声明一个有参数的构造函数
    private TestEnum(String name, int key){
        this.name = name;   //枚举值
        this.key = key;     //枚举值所传的参数
    }//默认私有类型
    private static TestEnum getKey(int key){
        for (TestEnum e:TestEnum.values()) {    //valus()方法遍历所有的枚举实例
            if (e.key == key) {
                return e;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getKey(2).toString());//返回name
        System.out.println("=======");
        System.out.println(getKey(1).name()); //返回name
    }
}
//output:
BLACK
=======
RED
  • 创造有参和无参的构造函数:
public enum TestEnum {
        RED,BULE,YELLOW,GREEN;
        
    private String name;
    private  int key;
    //声明一个有参数的构造函数
    private TestEnum(String name, int key){
        this.name = name;   //枚举值
        this.key = key;     //枚举值所传的参数
    }
    //声明一个无参数的构造函数
    private TestEnum(){

    }
   /* public void getInstance(){
        TestEnum testEnum = new TestEnum();//枚举不能产生实例对象 new
        // 原因: 自定义的枚举,都是继承 Enum 类构造函数默认为私有的
    }*///error

    public static void main(String[] args) {
        Class Test = TestEnum.class; //获得Class对象,类名.class (反射)

        //constructor的newInstance() 方法获取实例
        Constructor[] constructors = Test.getDeclaredConstructors();
        //getDeclaredConstructor():这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的

        for (int i = 0; i < constructors.length; i++) {
            System.out.println(constructors[i]);
        }
    }  
}
//output:
private com.TestEnum.TestEnum(java.lang.String,int)
private com.TestEnum.TestEnum(java.lang.String,int,java.lang.String,int)
默认会有两个参数
  • Tips: 枚举调用constructor.newInstance()方法,不能通过反射创造枚举对象/类,会出现 IllegalArgumenton 异常。
  • 枚举实现单利模式比较安全。
    源代码:
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");//不能通过反射创造枚举对象
        ConstructorAccessor ca = constructorAccessor;   // read volatile
public enum TestEnum {
        RED,BULE,YELLOW,GREEN;
        
    private String name;
    private  int key;
    //声明一个有参数的构造函数
    private TestEnum(String name, int key){
        this.name = name;   //枚举值
        this.key = key;     //枚举值所传的参数
    }
    //声明一个无参数的构造函数
    private TestEnum(){

    }

public static void main(String[] args) throws NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException {
        Class Test = TestEnum.class; //获得Class对象,类名.class (反射)
        
        Constructor[] constructors = Test.getDeclaredConstructors();
        //getDeclaredConstructor():这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的
        /*Constructor constructor = Test.getDeclaredConstructor(
                String.class, int.class,String.class, int.class);
        constructor.setAccessible(true);
        TestEnum t=(TestEnum)constructor.newInstance("green","绿色");//
        System.out.println("有参数的构造函数\t"+ t);*/
        Constructor constructor = Test.getDeclaredConstructor(
                String.class, int.class);
        constructor.setAccessible(true);
        TestEnum p=(TestEnum)constructor.newInstance();
        //newInstance()通过类的不带参数的构造方法创建这个类的一个对象
        System.out.println("无参数的构造函数\t"+p);
    }
}

//output:
在这里插入图片描述
Over…经过学习枚举,发现写一些类的时候可以方便的使用,也同时使用了上篇博客写到的反射的相关知识,查看反射内容请点击https://blog.csdn.net/nn1__2970/article/details/84171252,感觉不错。明天也要加油呀yayyayyya
写在最后:推荐一个“酷仔”滴公众号QAQAQQAQ!
最近推出了公众号 coding趣谈,一位在读学生的技术提升之路,为您提供一系列我在学习路上的笔记,经验,以及感悟。望与君共勉,共同进步! 欢迎大家来关注呦,这是小编的博客https://me.csdn.net/qq_38356149,可以先睹为快哈!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值