`
hwy1782
  • 浏览: 153353 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java 枚举类型使用

 
阅读更多

这几天在阅读《effective java》一书中enum相关的章节。笔记如下:

 

下面的例子中,提供了四种枚举型常量,这些枚举常量含有可以进行加减乘除操作的方法。

 

public enum Opration_V1 {
	
	PLUS,MINS,TIMES,DIVIES;
	
	double apply(double x,double y){
		switch (this) {
		case PLUS:
			return x+y;
		case MINS:
			return x-y;
		case TIMES:
			return x*y;
		case DIVIES:
			return x/y;
		}
		throw new AssertionError();
	}
	
}

 

 修改上述代码如下:

public enum Opration_V1 {
	
	PLUS,MINS,TIMES,DIVIES,
        ERROR;
	
	double apply(double x,double y){
		switch (this) {
		case PLUS:
			return x+y;
		case MINS:
			return x-y;
		case TIMES:
			return x*y;
		case DIVIES:
			return x/y;
		}
		throw new AssertionError();
	}
	
}

 

写道
上述代码中添加了一个新的枚举常量error,但是没有添加相应的apply()方法,因此在运行时调用Opration_V1.ERROR.apply()会报错。这种错误在编译期间不会出现,只是在运行期出现。

 

为了解决上述问题,可以采用如下的方法:

public enum Opration_V2 {
	
	PLUS{double apply(double x, double y) {return x+y;}},
	MINS{double apply(double x, double y) {return x-y;}},
	TIMES{double apply(double x, double y) {return x*y;}},
	DIVIES{double apply(double x, double y) {return x/y;}};
	
	abstract double apply(double x,double y);
	
}

 枚举类Opration_V2中添加了一个抽象方法apply();对于具体的枚举成员,都需要实现这个抽象方法。因此添加新的枚举成员的时候,编辑器会自动提示用户添加相应的apply方法。在编译期间就解决版本1中的问题。

 

可以对版本2进一步优化。

 

package com.enumDemo;

import java.util.Map;

import com.google.common.collect.Maps;

/**
 * @author E-mail: hwy1782@gmail.com
 * @date  : 2013-1-30 04:16:24
 */
public enum Opration_V3 {
	
	PLUS("+"){double apply(double x, double y) {return x+y;}},
	MINS("-"){double apply(double x, double y) {return x-y;}},
	TIMES("x"){double apply(double x, double y) {return x*y;}},
	DIVIES("/"){double apply(double x, double y) {return x/y;}};
	
	private String symbol;
	
	private Opration_V3(String symbol) {
		this.symbol = symbol;
	}
	
	abstract double apply(double x,double y);
	
	@Override
	//use symbol to display enum
	public String toString() {
		//Returns the name of this enum constant, as contained in the declaration
		return symbol;
	}
	
	/**
	 * get enum of the symbol 
	 * @param symbol
	 * @return
	 */
	public static Opration_V3 formString(String symbol){
		return stringToEnum.get(symbol);
	}
	
	private static final Map<String,Opration_V3> stringToEnum = Maps.newHashMap();
	
	static{
		for(Opration_V3 op : Opration_V3.values()){
			stringToEnum.put(op.toString(), op);
		}
	}
	
	
	
}

 

上述部分主要进行了如下几点优化:

1.将枚举常量与特定的符号关联起来,通过重写enum的toSting()方法,对外展示枚举常量的symbol

2.添加一个fromString()方法,返回symbol对应的枚举常量。

 

上面的例子还存在一些问题。版本3中每一个enum类型对应一个apply()方法,但是如果存在一种情况:几个enum常量对应相同的apply()方法,是不是每个enum常量都把相应的apply()方法再拷贝一遍呢?下面有一种解决方案:采用switch的方式,匹配对应的方法:

package com.enumDemo;
/**
 * @author E-mail: hwy1782@gmail.com
 * @date  : 2013-1-31 上午11:32:51
 * Payroll 枚举工资单,计算每天的工资
 * 
 * </br>缺点:
 * </br>
 * 添加一个新的enmu,忘记在pay()方法中添加相应的switch条件的话,就会采用default的计算pay的方法。
 * 
 */
public enum PayrollDay_v1 {

	MONDAY,TUESDAY,WEDNESDAY,THRSDAY,FRIDAY,SAYURDAY,SUNDAY;
	
	private static final int DEFAUL_WORK_HOUR = 8;
	
	double pay(double workHoues,double payRate){
		double basicPay = DEFAUL_WORK_HOUR * payRate;
		double overTimePay = 0;
		switch (this) {
		case SAYURDAY: case SUNDAY:
			overTimePay = workHoues * payRate * 2;
		default:
			overTimePay = (workHoues - DEFAUL_WORK_HOUR) * payRate * 2;
		}
		
		return basicPay + overTimePay;
	}
	
}

 

 但是上述方案同样存在一些问题,新增一个enm常量,但是忘记添加相应的switch条件,则这个新增的enum会执行默认的方法,存在很大的隐患。

 

下面提供了一种解决方案,枚举策略方法:

package com.enumDemo;
/**
 * @author E-mail: hwy1782@gmail.com
 * @date  : 2013-1-31 上午11:32:51
 * Payroll 枚举工资单,计算每天的工资
 * 
 * </br>改进点:
 * </br>
 * 修复版本1中存在的缺陷:
 * 新增一个枚举的时候忘记添加相应的计算工资的方法。</br>
 * 方法:
 * 1.添加一个abstract 方法,每个枚举常量必须实现这个abstract方法,在这个abstract方法中实现每个enum常量的pay()方法。
 * 但是上述的方法有一个缺陷,每个枚举常量必须都实现这个abstract方法,不能做到这个方法的复用。
 * 
 * 2.此处使用策略枚举(strategy enum)来解决这个问题
 * 枚举策略的使用条件是:
 * <br/>
 * 枚举常量中: 存在多个常量共用一个方法的时候,抽象公用方法为枚举
 * <br/>
 * 可以将这种策略枚举添加在外部枚举常量的构造函数中,解决新加常量时遗忘添加方法的问题
 * 
 */
public enum PayrollDay_v2 {

	MONDAY(PayType.WEEKDAY),
	TUESDAY(PayType.WEEKDAY),
	WEDNESDAY(PayType.WEEKDAY),
	THRSDAY(PayType.WEEKDAY),
	FRIDAY(PayType.WEEKDAY),
	SAYURDAY(PayType.WEEKDAY),
	SUNDAY(PayType.WEEKEND);
	
	private final PayType payType;
	
	PayrollDay_v2(PayType type){
		this.payType = type;
	}
	
	
	public double pay(double workHourse,double payRate){
		return payType.pay(workHourse, payRate);
	}
	
	//策略枚举
	private enum PayType{
		WEEKDAY{
			@Override
			double overtimePay(double workHourse,double payRate) {
				return workHourse > DEFAUL_WORK_HOUR ? 0 : (workHourse - DEFAUL_WORK_HOUR)*payRate;
			}
		},
		WEEKEND{
			@Override
			double overtimePay(double workHourse,double payRate) {
				return workHourse * payRate;
			}
		};
		
		static final int DEFAUL_WORK_HOUR = 8;
		
		abstract double overtimePay(double workHourse,double payRate);
		
		double pay(double workHourse,double payRate){
			double basicPay = workHourse * payRate;
			return basicPay + overtimePay(workHourse, payRate);
		}
		
	}
	
}

 

测试类如下:

package com.enumDemo;

import org.junit.Test;

/**
 * 
 * @author hongye.hwy
 * 
 */
public class PayrollDay_v2_Drive {

	private static final double DEFAULT_PAY_RATE = 9.8;
	
	@Test
	public void test_PayrollDay() {

		double workHourse = 8;
		
		System.out.printf("%s work %f hours will get %f$",
				PayrollDay_v2.SAYURDAY,workHourse,PayrollDay_v2.SAYURDAY.pay(8, DEFAULT_PAY_RATE));
	}

}

 

 

 

分享到:
评论

相关推荐

    Java枚举类型Enum的用法

    接下来,我们将深入探讨Java枚举类型的使用方法及其相关知识点。 1. **枚举的声明与初始化** 枚举类型的声明方式类似于类,但以`enum`关键字开头。例如: ```java enum Color { RED, GREEN, BLUE } ``` 这里...

    java枚举类型说明

    使用Java枚举类型相比传统的`public static final`变量有许多优势: 1. **类型安全**: 枚举类型确保只能使用预定义的值,这有助于避免程序错误。 2. **自动实现接口**: 枚举类型自动实现了`Serializable`和`...

    简单总结java枚举类型

    Java枚举类型是Java语言中一种特殊的类,用于定义固定的常量集合,它提供了一种安全、类型化的方式来表示一组有限的值。枚举在Java中被引入为一个完整的类型,不同于C++中的枚举,这使得Java枚举更加强大且易于使用...

    Java枚举类型.pdf

    总结起来,Java枚举类型是一个强大的工具,它可以替代`static final`常量来表示一组固定的值,提供类型安全、易于维护的代码。通过枚举,我们可以更方便地管理常量,减少错误,并增加代码的灵活性。枚举是Java中一个...

    理解java枚举类型

    Java枚举类型是Java语言中的一种特殊的类,用于定义一组固定的常量集合。它在Java中扮演着重要的角色,提供了一种安全、类型化的常量表示方式,比传统的final static变量更具有优势。理解Java枚举类型对于编写高质量...

    如何使用Java枚举类型

    一个关于JAVA枚举类型的MHT文件,包含JAVA枚举类型的用法,以及JDK版本的问题。

    JAVA枚举类型的用法详解

    下面我们将深入探讨Java枚举类型的常见用法。 首先,枚举类型在本质上等同于定义了一组静态常量。创建枚举类型的语法如下: ```java public enum Belle { para1, para2, para3, para4; } ``` 这会创建一个名为`...

    全面掌握java枚举类型(enum-type)1

    Java 中使用关键字 enum 来定义一个枚举类型。例如: ```java public enum Season { SPRING, SUMMER, AUTUMN, WINTER; } ``` 特点 Java 定义枚举类型的语句很简约。它有以下特点: 1. 使用关键字 enum 2. 类型...

    java枚举结果类、根据状态值获取枚举值

    java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” &lt;/#list&gt;

    java枚举类型enum的使用

    ### Java 枚举类型 enum 的使用详解 #### 一、枚举类型概述 在 Java 中,枚举(enum)是一种特殊的类,它被用来表示一组固定的常量值。枚举类型自 JDK 1.5 开始引入,为开发者提供了一种更加安全、简洁的方式来...

    高阶Java-Java枚举类型 enum 应用详解

    枚举类型可以有自己的构造器,但只能在枚举声明时使用,并且不能是公有的。这允许在创建枚举实例时进行初始化操作。 ```java public enum Planet { MERCURY(3.303e+23, 2.4397e6), VENUS(4.869e+24, 6.0518e6), ...

    Java 枚举类型使用小技巧

    本篇文章将探讨如何在Java中巧妙地使用枚举类型,特别是在枚举变量较多且存在分类关系时的管理策略。 首先,我们可以看到在提供的代码示例中,作者创建了一个名为`EnumInter`的接口,用于实现枚举类型的分类。接口...

    java枚举类型优秀源代码

    - **自动实现接口**:枚举类型会自动实现`java.lang.Enum&lt;E&gt;`接口,其中`E`是枚举类型的名称。 - **安全性**:枚举类型的成员是固定的,不允许外部添加或修改成员。 - **单例模式**:每个枚举成员都是单例的,只能被...

    java枚举实例代码

    Java枚举(enum)是Java语言中的一种特殊数据类型,用于定义一组有限的常量,这些常量在程序中作为固定的值使用。枚举在Java中被引入,目的是为了更好地管理和使用常量,提高代码的可读性和安全性。在本实例代码中,...

    JAVA枚举类型[归纳].pdf

    JAVA枚举类型[归纳].pdf

    Java 枚举类型案例.zip

    在本压缩包中,"Java 枚举类型案例"可能包含了多个示例,以帮助我们深入理解Java枚举类型的使用。 1. **枚举的定义** 在Java中,枚举是通过关键字`enum`来定义的。例如,创建一个表示星期的枚举类型: ```java ...

    java枚举的一个实例

    总的来说,Java枚举提供了一种强类型、安全且易于使用的机制来表示固定集合的值。通过枚举,我们可以更好地组织代码,减少错误,并提升程序的可维护性。在JavaDemo项目中,可能包含了各种使用枚举的示例,包括但不...

    列举java 枚举相关信息

    ### Java 枚举类型详解 #### 一、引言 ...通过以上的介绍,我们可以看到Java枚举类型不仅提供了类型安全的保障,还为开发者带来了极大的灵活性。合理地使用枚举类型,可以显著提高代码的质量和可维护性。

Global site tag (gtag.js) - Google Analytics