枚举类
//com.insanus.EnumClass.java
package com.insanus;
public class EnumClass {
public static void main(String[] args) {
for(TryEnum i: TryEnum.values()) {
System.out.println(i);
//values()返回enum实例的数组
}
//关于Enum的静态方法valueOf
//static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
TryEnum x = Enum.valueOf(TryEnum.class, "One");
TryEnum y = TryEnum.valueOf("One");
System.out.println(x == y);
//这里显示是True
}
}
enum TryEnum {
One, Two
}/* Output:
One
Two
True
*///:~
因为Enum类中并没有values方法
所以我们来探讨一下values的神秘之处
//com.insanus.Values.java
import java.lang.reflect.Method;
import java.util.Set;
import java.util.TreeSet;
public class Values {
public static void main(String[] args) {
Class t = Enum.class;
Class i= TryEnum.One.getClass();
Set<String> temp = new TreeSet<>();
for (Method in: t.getMethods()) {
temp.add(in.getName());
}
for (Method in: i.getMethods()) {
if(!temp.contains(in.getName()))
System.out.println(in.getName() + "\n" + in.toString());
}
}
}
enum TryEnum {
One
}/* Output:
values
public static com.insanus.TryEnum[] com.insanus.try_module.TryEnum.values()
*///:~
我们观察到,values并不是Enum的方法,但是在创建enum实例的时候,却出现了这个方法。可以推导出的是,这个values方法是编译器添加的静态方法。
我们写了一小段代码测试一下。
enum TryEnum {
One;
public TryEnum[] test() {
return values();
}
}
通过
static enum
//com.insanus.EnumClass1.java
package com.insanus;
public enum EnumClass1 {
One
}
//com.insanus.TryEnum1.java
package com.insanus;
import static com.insanus.EnumClass1.*;
public TryEnum1 {
public static void main(String[] args) {
EnumClass1 t = One;
}
}
enum添加新方法
因为enum可以当做一个特殊的类,所以可以添加和覆盖方法。甚至可以添加main。
//com.insanus.MethodEnum.java
package com.insanus;
public enum MethodEnum {
One;
//注意,不能没有添加序列(singleton的enum实现)
public static void main(String[] args) {
System.out.println("From Enum");
}
}
switch和enum
//com.insanus.SwitchEnum.java
package com.insanus;
public enum SwitchEnum {
One, Two;
public static void main(String[] args) {
SwitchEnum i = SwitchEnum.Two;
switch(i) {
case One:
System.out.println("One");
break;
case Two:
System.out.println("Two");
break;
}
}
}/* Output:
Two
*///:~
使用接口组织枚举
//com.insanus.Values1.java
package com.insanus;
public class Values1 {
public static void main(String[] args) {
TryEnum1 i = TryEnum1.One.ONE;
}
}
//嵌套接口
interface TryEnum1 {
enum One implements TryEnum1 {
ONE, TWO
}
enum Two implements TryEnum1 {
THREE
}
}
解释EnumSet和EnumMap的工作原理
EnumSet
从上面的文档,我们多少能猜的出。EnumSet利用了enum的“单例”特性,当每次添加进一个enum,就为其创造实例。
//com.insanus.TestEnumSet.java
package com.insanus;
public class TestEnumSet {
public static void main(String[] args) {
EnumSet<TestEnum> i = EnumSet.noneOf(TestEnum.class);
i.add(TestEnum.Two);
i.add(TestEnum.Two);
System.out.println(i);
}
}
enum TestEnum {
One, Two;
}/* Output:
[Two]
*///:~
EnumMap
我们观察一下这句话
EnumMap<K extends Enum<K>,V>
应该和EnumSet的原理差不多
常量相关的方法
//com.insanus.EnumModel.java
package com.insanus;
public enum EnumModel {
One(5) {
@Override
void view() {
System.out.println("来自One, id为" + super.type);
}
},
Two(7) {
@Override
void view() {
System.out.println("来自Two, id为" + super.type);
}
};
abstract void view();
private int type;
EnumModel(int type) {
this.type = type;
System.out.println("父类构造器");
}
public static void main(String[] args) {
EnumModel.One.view();
}
}/* Output:
父类构造器
父类构造器
来自One, id为5
*///:~
我们观察到父类构造器被调用了两次,由此可以得出,enum为每个常量都生成了一个实例。