Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29365
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-17 16:06
文章分类

全部博文(13)

文章存档

2017年(5)

2016年(8)

我的朋友

分类: Java

2017-02-15 19:58:19

枚举类是java在jdk5.0加入的语法,通常用于描述 仅包含有限种类型的 变量。

使用enum关键字声明,格式如下。可以在枚举类中自定义内部变量,抽象方法,在枚举值的声明中要实现此抽象方法。(枚举值就是对枚举类的匿名继承

粗浅理解:

枚举类是父类,声明了抽象方法会自动变更抽象父类。

枚举值是枚举类的匿名实现类,必须实现父类的抽象方法,并继承父类声明的所有变量和普通方法。

枚举值的实例在枚举类初始化时会自动生成,且为单例实现,不需要手动new。(因为在枚举类的静态代码块执行时,已经可以通过枚举类.values()获取全部枚举值的实例)

最简单:

 enum RainbowColor { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE }

较复杂:

enum InfoFilterEnum {
	SCORE("score") {
		@Override
		public boolean filterInfo(InfoDO info, RuleDO rule) {
			RuleOperaionEnum operationEnum = RuleOperaionEnum.findByName(rule.getOperation());
			if (operationEnum == null) {
				return true;
			}
			return operationEnum.validate(info.getScore(), rule.getValue());
		}
	}, HAS_PREPAY("has_prepay") {
		@Override
		public boolean filterInfo(InfoDO info, RuleDO rule) {
			RuleOperaionEnum operationEnum = RuleOperaionEnum.findByName(rule.getOperation());
			if (operationEnum == null) {
				return true;
			}
			return operationEnum.validate(info.getHasPrepay(), rule.getValue());
		}
	}, HAS_ZL("has_zl") {
		@Override
		public boolean filterInfo(InfoDO info, RuleDO rule) {
			RuleOperaionEnum operationEnum = RuleOperaionEnum.findByName(rule.getOperation());
			if (operationEnum == null) {
				return true;
			}
			return operationEnum.validate(info.getHasZl(), rule.getValue());
		}
	}, HAS_HOUR_ROOM("has_hour_room") {
		@Override
		public boolean filterInfo(InfoDO info, RuleDO rule) {
			RuleOperaionEnum operationEnum = RuleOperaionEnum.findByName(rule.getOperation());
			if (operationEnum == null) {
				return true;
			}
			return operationEnum.validate(info.getHasHourRoom(), rule.getValue());
		}
	}, HAS_DAY_ROOM("has_day_room") {
		@Override
		public boolean filterInfo(InfoDO info, RuleDO rule) {
			RuleOperaionEnum operationEnum = RuleOperaionEnum.findByName(rule.getOperation());
			if (operationEnum == null) {
				return true;
			}
			return operationEnum.validate(info.getHasDayRoom(), rule.getValue());
		}
	};
	
	String code;
	InfoFilterEnum(String code) {
		this.code = code;
	}
	
	private static Map cache = new HashMap<>();
	
	static {
		for (InfoFilterEnum filter : InfoFilterEnum.values()) {
			cache.put(filter.code, filter);
		}
	}
	
	abstract public boolean filterInfo(InfoDO info, RuleDO rule);
	
	public static InfoFilterEnum findByCode(String code) {
		return cache.get(code);
	}
}


 


从例2可以获得很多枚举设计经验

tips:

1. 由于枚举值的种类有限,故一般定义为不可变类,内部变量不用设计setter,仅在构造方法中初始化。

在构造之后,每个枚举值都拥有不可变的code作为id,便于在枚举类中设计获取枚举值的方法(见3)。

2. 在枚举类中设计抽象方法,并在枚举值中实现该方法(枚举值定义其实是匿名类)。这样对不同枚举值有不同实现,又可以在逻辑调用此枚举时使用同一个方法。

例子中,filterInfo在外部的业务逻辑中,用于验证info中某变量是否符合rule的规则,而针对不同的枚举值(情况),会获取Info中不同的变量去做规则匹配。

3. 在枚举类中设计静态Map,并用静态初始化块生成code-枚举值的映射(使用枚举类.values()方法可以遍历枚举值的实例),可以方便根据code获取枚举值。

例子中,findByCode可以在业务逻辑中,用于获取某个code对应的枚举值实例,并调用filterInfo完成规则匹配。

阅读(902) | 评论(0) | 转发(0) |
0

上一篇:java类中变量的初始化

下一篇:EhCache

给主人留下些什么吧!~~