public enum Color {
RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, PINK, BROWN, BLACK, WHITE;
}每个我们写的 enum 类都会默认继承于一个抽象类 Enum,如下图所示:

而这个 Enum 抽象类中有挺多方法,如下所示:

下面是使用举例:
public static void main(String[] args) {
// 使用Color.RED直接访问枚举元素,或者直接RED都行,但不能使用new来生成枚举类对象
Color color = Color.RED;
System.out.println(color.name()); // 输出颜色名称
System.out.println(color.ordinal()); // 输出颜色的序号
System.out.println(color); // 直接输出颜色对象
System.out.println(color.describeConstable()); // 输出颜色的描述信息
System.out.println(Color.valueOf("BLACK")); // 通过名称获取枚举值
// 有个比较特殊的是values()方法,它可以返回所有枚举值数组,它不存在Enum中,而是在编译时由编译器生成的。
// 但是如果枚举值太多,可能导致内存溢出,所以一般不用这个方法。
System.out.println("----------------------输出所有枚举元素:");
Color[] colors = Color.values();
for(int i = 0; i < colors.length; ++i) {
System.out.println(colors[i] + " " + colors[i].ordinal());
}
Color c2 = new Color(); // ❌不能实例化枚举类,只能通过枚举值访问其属性和方法。
}
// 运行结果:
RED
0
RED
Optional[EnumDesc[Color.RED]]
BLACK
----------------------输出所有枚举元素:
RED 0
GREEN 1
BLUE 2
YELLOW 3
ORANGE 4
PURPLE 5
PINK 6
BROWN 7
BLACK 8
WHITE 9这里要注意 values() 是由 Java 编译器为每个枚举类自动生成的静态方法,所以在 Enum 类里是找不到它的源码的,但每个具体的枚举类都有它。
还有就是枚举类内也可以有方法,并且这些方法只能通过枚举元素来调用,而不能直接通过枚举类名来调用,如下图所示:

private枚举类的构造方法是隐式 private 的,是为了:
enum 的封闭性)
首先枚举类也是可以写构造函数,然后枚举元素可以进行构造,如下所示:
public enum Color {
RED("red", 1), GREEN("green", 2), BLUE("blue", 3);
private String name;
private int value;
// 构造函数默认就是private,不写也可以,但是不能写其它的访问权限
private Color(String name, int value) {
this.name = name;
this.value = value;
}
public static void main(String[] args) {
Color c = Color.RED;
System.out.println(c.name);
System.out.println(c.value);
}
}
// 运行结果:
red
1然后测试一下不同对象引用同一个枚举元素,是不是同一地址:
public static void main(String[] args) {
Color c1 = Color.RED;
Color c2 = Color.RED;
System.out.println(c1 == c2); // true
}很明显不同对象引用同一个枚举元素,都是同一个对象。
然后看一下是不是能够在类内调用构造方法:
public static void main(String[] args) {
Color c = new Color(); // ❌报错:无法实例化枚举类型
}那么就想,能不能用反射来设置访问权限,强制调用构造方法,如下所示:
public static void main(String[] args) {
try {
// 先获取构造函数,再设置Accessible为true
Class<?> cs = Class.forName("EnumDemo.Color");
Constructor<?> ctor = cs.getDeclaredConstructor(String.class, int.class);
ctor.setAccessible(true);
// 调用构造函数创建对象
Color c = (Color)ctor.newInstance("yellow", 4);
System.out.println(c.name + " " + c.value);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}然后报了如下错误:

其实这个参数错误,是因为每个枚举类都默认继承了 Enum,而 Enum 类的构造方法又有两个参数,如下所示:

这时就需要一起放在我们的枚举类的参数列表中传入才行:
Constructor<?> ctor = cs.getDeclaredConstructor(String.class, int.class, String.class, int.class);解决上述问题之后,此时又有一个错误如下所示:

点击第二行跳转过去看看源码:

Enum 类同样有构造方法,但一定得是 private 修饰。Enum 类的每一个枚举元素都是【单例】。Enum 类型的类不能通过调用【构造方法】来创建实例。Enum 类型的类不能通过【反射】来创建新的实例,因为 Enum 的实例在编译时就已经确定,且 JVM 保证了这些实例的唯一性。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。