欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

神奇的java枚举

程序员文章站 2022-03-03 19:49:07
...
除了不能继承自一个enum之外,基本上可以将enum看做一个常规的类,即可以添加方法,可以有main()方法,可以定义构造器
package com.myjava.testenum;
/**
* @author Kaili
* @date 创建时间:2009-10-14 下午10:05:07
* @version
*/
public enum TestEnum{

A,
B("First");
private String description;
//默认构造器
private TestEnum(){
}
//带参数的构造器
private TestEnum(String description){
this.description = description;
}

//覆盖enum方法
public String toString(){
String id = name();
String lower = id.toLowerCase();
return id + "(" + lower + ")";
}

public String getDescription(){
return description;
}
public static void main(String[] args){
for(TestEnum te : TestEnum.values()){
System.out.println(te + ":" + te.getDescription());
}
}
}

上面提到了values()方法,但是通过研究enum的源代码发现,并没有此方法,我们利用反射机制,验证一下
import java.lang.reflect.*;
import java.util.*;
import net.mindview.util.*;

enum Explore {
HERE, THERE
}

public class Reflection {
// 分析class,获得此类的接口,基类,包含的方法
public static Set<String> analyze(Class<?> enumClass) {
System.out.println("正在分析"+enumClass);
System.out.print("实现的借口有:");
//遍历依赖的接口
for (Type t : enumClass.getGenericInterfaces())
System.out.print(t + "; ");
System.out.println();
//获得基类
System.out.println("此Class的超类: " + enumClass.getSuperclass());
System.out.print("此Class包含的方法: ");
Set<String> methods = new TreeSet<String>();
//遍历包含的方法,并添加到一个Set集合
for (Method m : enumClass.getMethods())
methods.add(m.getName());
System.out.println(methods);
//返回所有方法
return methods;
}

public static void main(String[] args) {
Set<String> exploreMethods = analyze(Explore.class);
System.out.println("-------------------------------------------");
Set<String> enumMethods = analyze(Enum.class);
//验证子类是不是包含父类所有方法
System.out.println("子类是不是包含父类所有方法: " + exploreMethods.containsAll(enumMethods));
System.out.print("子类移除父类的所有方法后,剩下的方法 ");
exploreMethods.removeAll(enumMethods);
System.out.println(exploreMethods);
}
}

输出结果
[quote]正在分析class enumerated.Explore
实现的借口有:
此Class的超类: class java.lang.Enum
此Class包含的方法: [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
-------------------------------------------
正在分析class java.lang.Enum
实现的借口有:java.lang.Comparable<E>; interface java.io.Serializable;
此Class的超类: class java.lang.Object
此Class包含的方法: [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
子类是不是包含父类所有方法: true
子类移除父类的所有方法后,剩下的方法 [values][/quote]
由此可以发现values()方法是由编译器添加的static方法,顺便说下,编译器还添加了一个valueOf()方法
如果你将enum实例向上转型为Enum,那么values()方法就不可访问了,但是我们可以使用Class的getEnumConstants()方法(注:如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null)

因为enum都集成Enum类,由于java不支持多继承,所以enum不能再集成其他类,但是可以同时实现一个或多个接口

用enum实现接口的方法实现一个菜单管理
public enum Meal2 {
// 利用构造器初始化
APPETIZER(Food.Appetizer.class), MAINCOURSE(Food.MainCourse.class), DESSERT(
Food.Dessert.class), COFFEE(Food.Coffee.class);
private Food[] values;

private Meal2(Class<? extends Food> kind) {
values = kind.getEnumConstants();
}

public interface Food {
// 定义开胃菜
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}

// 定义主菜
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMOUS, VINDALOO;
}

// 定义甜点
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE, FRUIT, CREME_CARAMEL;
}

// 定义咖啡
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
}
}

Enum关于常量定义的使用举例:
import java.util.*;
import java.text.*;

public enum ConstantSpecificMethod {
DATE_TIME {
//实现抽象方法
String getInfo() {
return
DateFormat.getDateInstance().format(new Date());
}
},
CLASSPATH {
String getInfo() {
return System.getenv("CLASSPATH");
}
},
VERSION {
String getInfo() {
return System.getProperty("java.version");
}
};
//定义一个抽象方法
abstract String getInfo();
public static void main(String[] args) {
for(ConstantSpecificMethod csm : values())
System.out.println(csm.getInfo().length());
}
}