论坛首页 Java企业应用论坛

神奇的java枚举

浏览 18710 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (12) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-10-14   最后修改:2009-10-15
除了不能继承自一个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);
	}
}

输出结果
引用
正在分析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]

由此可以发现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());
  }
}
   发表时间:2009-10-14  
帖子有点单薄,但是我来顶你!
0 请登录后投票
   发表时间:2009-10-15  
.NET中 枚举得到了充分的利用
0 请登录后投票
   发表时间:2009-10-15  
enum就是一个废品!还不如简单的做成像C那样的实用,想ORM存储到数据库都困难,变态的SUN公司。。。
0 请登录后投票
   发表时间:2009-10-15  
myreligion 写道
enum就是一个废品!还不如简单的做成像C那样的实用,想ORM存储到数据库都困难,变态的SUN公司。。。


JPA和hibernate实现这个很简单 内建就是支持的
0 请登录后投票
   发表时间:2009-10-15  
真的 java的枚举 我感觉很失败 比.net的都差很远
0 请登录后投票
   发表时间:2009-10-15  
george_space 写道
帖子有点单薄,但是我来顶你!


有机会看看你的厚帖?
0 请登录后投票
   发表时间:2009-10-15  
myreligion 写道
enum就是一个废品!还不如简单的做成像C那样的实用,想ORM存储到数据库都困难,变态的SUN公司。。。


enum是一种比较固定的有限枚举,算是一种类型的数据结构,
这种结构的数据有什么业务场景需要存入数据库吗?
0 请登录后投票
   发表时间:2009-10-15  
star022 写道
myreligion 写道
enum就是一个废品!还不如简单的做成像C那样的实用,想ORM存储到数据库都困难,变态的SUN公司。。。


enum是一种比较固定的有限枚举,算是一种类型的数据结构,
这种结构的数据有什么业务场景需要存入数据库吗?


想想你存入数据库的是什么? 一些毫无意义的符号而已,0,1,2,3,4,当你在运行报表的时候,这种语义缺乏会造成很大的困扰。比如 男=0,女=1, 最后打印报表时,0 和 1 根本毫无意义。

男女只是很简单的一个例子,复杂的应用里,有很多字典表,这些字典表必须体现出其词性才有意义。
0 请登录后投票
   发表时间:2009-10-15  
感谢大虾们的捧场,但是总感觉在现实开发中很少见到enum的例子,大家能不能分享下自己的经验?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics