枚举
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。正好是可以通过枚举来使用这些数据集。
- 定义枚举类型:使用关键字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; //(分号可有可无) 定义对象,枚举的实例是常量
}
- 常用的枚举类型的方法:
- 所有的枚举类型均隐式地继承于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
- 声明枚举类型的其他成员方法:
- 在枚举类型中,除了声明枚举值之外,还可以声明其他类成员,包括构造方法、方法和数据成员。
注意:枚举类的构造方法与一般类的构造方法不同,枚举类构造方法的访问修饰符只能为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,可以先睹为快哈!