概述
枚举类型Enum是类的一种特殊的形式,用于声明一组命名的常量。
我们先声明一个名为Color的枚举类型,了解一下基本格式~~
enum Color{
RED,GREEN,WHITE,BLACK //BLACK后面可以加;也可以不加
}
声明和使用
[枚举修饰符] enum 枚举名{
枚举体[;]
}
- 枚举修饰符只允许public,不允许abstract 和 final 修饰符;枚举不能是抽象的,也不允许派生
- 枚举的定义必须大写
- 枚举的构造函数必须为私有的
- 访问枚举类的方式与访问静态常量字段相似,为
- 枚举名.枚举成员;
- 枚举不能产生实例对象 ,不能new
- 原因:自定义的枚举都是继承Enum, 构造函数默认为私有的
- 枚举类型可以作为switch的参数
enum Color{
RED,GREEN,WHITE,BLACK
}
public class Test1 {
public static void main(String[] args) {
Color color = Color.BLACK;
switch (color){
case RED:
System.out.println("RED");
break;
case GREEN:
System.out.println("GREEN");
break;
case WHITE:
System.out.println("WHITE");
break;
case BLACK:
System.out.println("BLACK");
break;
}
}
}
输出结果:BLACK
枚举类的成员方法
ordinal()方法
- 返回枚举常量的序数
- 在枚举声明中,其初始常量序数为0
来一段代码展示啦~~~~~
// Color color = new Color(); error
Color color = Color.BLACK;
System.out.println(color.ordinal());
输出结果: 3
toString()方法、name()方法
- 返回枚举常量的名称
System.out.println(color.name());
System.out.println(color.toString());
结果:
BLACK
BLACK
valueOf()方法
- 返回带指定名称的指定枚举类型的枚举常量
System.out.println(Color.valueOf("BLACK"));
结果
BLACK
equals()方法
Color color = Color.BLACK;
Color color1 = Color.RED;
System.out.println(color.equals(color1));
System.out.println(color == color1);
结果
false
false
comperTo()方法
- 比较此枚举类与指定对象的顺序
System.out.println(color.compareTo(color1));
System.out.println(color1.compareTo(color));
结果
3
-3
getDeclaringClass()方法
System.out.println(color.getDeclaringClass());
结果
class com.daily.Color
values()方法
- 返回一个枚举类型的数组,其中数组元素即为该枚举类元素列表中的元素
- 这个方法是由编译器自己生成的一个静态方法
for (Color c:Color.values()) {
System.out.println(c);
}
System.out.println("====================");
Color[] colors = Color.values();
for (int i = 0; i < colors.length; i++) {
System.out.println(colors[i]);
}
有参数的
public enum TestEnum {
RED("red",1),GREEN("green",2),WHITE("white",3),BLACK("black",4);
private final String name;
private final int key;
//这里是两个参数的构造函数,定义的枚举类也必须有两个参数,否则报错
private TestEnum(String name,int key){
this.name = name;
this.key = key;
}
public static TestEnum getKey(int key){
for (TestEnum color : TestEnum.values()){
if (color.key == key){
return color;
}
}
return null;
}
public static void main(String[] args) {
System.out.println(getKey(2).toString());
}
}
输出结果:
GREEN
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException {
Class colorEnum = TestEnum.class; //得到class对象
//通过class对象调用私有构造函数
Constructor constructor = colorEnum.getDeclaredConstructor(String.class,int.class);
constructor.setAccessible(true); //跳过访问性检查
TestEnum p = (TestEnum) constructor.newInstance("green","绿色"); //传入两个参数
System.out.println("有参数的构造函数\t"+p);
}
为什么会报错呢????
我们来打印一下他的私有构造函数
Class colorEnum = TestEnum.class; //得到class对象
Constructor[] constructors = colorEnum.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
}
我们发现这里有四个参数
emmmmmmmmm…???
那我们给四个参数试一下咯。。。。。
Constructor constructor = colorEnum.getDeclaredConstructor(String.class,int.class, String.class,int.class);
constructor.setAccessible(true); //跳过访问性检查
TestEnum p = (TestEnum) constructor.newInstance("green","绿色"); //传入两个参数
System.out.println("有参数的构造函数\t"+p);
为什么还会报异常呢???
我们来看一下源码叭…
这也是下面这个面试问题的答案啦:
普通类把构造函数私有化,虽然外部无法直接new对象,但是依然可以通过反射来访问该类私有的构造函数生成对象,
但是枚举类的构造函数只能是私有的,得到这个构造函数后,却不能通过newInstance得到实例。
这也是为什么枚举实现单利模式最安全的原因
emmmmmmmmm…
那为什么要传入四个参数呢?????
那我们再来看一下源码啦…
现在问题就都解决了叭~~~~