我们存放一些静态变量,像是一些变量和设置,等等等等,我们尽量使用ENUM,因为ENUM是不可实例化和继承的,所以他很安全,它是在程序一开始运行的时候进行一些编译,修改ENUM不需要再次编译。

在什么时候用ENUM呢。摘录如下。

Use enums when you want to define a range of values that something can be. Colour is an obvious example like:

public enum Colour
{
White,
Red,
Blue
}
Or maybe a set of possible things like: (Example I stole from here as I'm lazy) [FlagsAttribute]
enum DistributedChannel
{
None = 0,
Transacted = 1,
Queued = 2,
Encrypted = 4,
Persisted = 16,
FaultTolerant = Transacted | Queued | Persisted
}
Constants should be for a single value, like PI. There isn't a range of PI values, there is just PI.

一个简单应用

public enum CircleArea {
CIRCLEONE(1.2),
CIRCLETWO(2.5),
CIRCLETHREE(3.5); private final double r; private static final double PI=3.14; CircleArea(double r) {
this.r=r;
} public double R(){
return r;
} public double Area(){
return r*r*PI;
} public double SomeArea(int Some){
return Some*r*r*PI;
}
} 测试

for (CircleArea c:CircleArea.values() ){

System.out.println(c+" "+c.R()+" "+c.SomeArea(3)+"");
}

 

使用ENUM的时候,如果enum里面有ABstract ,则声明的时候也必须要有,所以以下尽量使用Operation2的形式。

public enum Operation {
PLUS, MINUS, TIMES, DIVDE;
double apply(double x, double y) {
switch (this) {
case PLUS:
return x + y;
case MINUS:
return x - y;
case TIMES:
return x * y;
case DIVDE:
return x / y;
}
throw new AssertionError("未定义类型" + this);
}
}
public enum Operation2 {
PLUS {
double apply(double x, double y) {
return x + y;
}
},
MINUS {
double apply(double x, double y) {
return x - y;
}
},
TIMES {
double apply(double x, double y) {
return x * y;
}
},
DIVIDE {
double apply(double x, double y) {
return x / y;
}
}; abstract double apply(double x, double y);
} /////////////////////////带符号输出的
public enum Operation3 {
PLUS("+") {
double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
double apply(double x, double y) {
return x - y;
}
},
TIMES("*") {
double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
double apply(double x, double y) {
return x / y;
}
}; private final String symbol; Operation3(String symbol) {
this.symbol = symbol;
}
@Override public String toString(){
return symbol;
} abstract double apply(double x, double y);
}

除了EnumSet和EnumMap,都不要使用ordinals。

public enum WrongIdEnum {
FIRST,SECOND,THIRD;
public int getId(){
return ordinal()+1;
}
} public enum IdEnum {
FIRST(1),SECOND(2),THIRD(3); private final int id;
IdEnum(int id){
this.id=id;
}
public int getId(){
return id;
}
}

上面两个Enum都可以实现返回ID的功能,但是千万不要使用第一个类型,因为第一个类型非常不方便增删,如果我在中间删掉一个定量,因为ordinals代表的是当前在Enum的排序第几个,后面所代表的意义全部会乱。

在JAVA中,尽量不要使用位操作定量,可以使用EnumSet来替换,EnumSet比较安全且高效,继承了Enum的所有优点,什么是位操作定量,需要了解一下。附上EnumSet的一个实现。

public enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY;
} public class Worker {
private String name;
private Set<Day> avalibleDay;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Day> getAvalibleDay() {
return avalibleDay;
}
public void setAvalibleDay(Set<Day> avalibleDay) {
this.avalibleDay = avalibleDay;
}
public Worker(String name, Set<Day> avalibleDay) {
super();
this.name = name;
this.avalibleDay = avalibleDay;
}
} public static void getNoDay(Worker[] work){//哪天都没人来
Set<Day> days = EnumSet.allOf(Day.class);
for(Worker w:work){
days.removeAll(w.getAvalibleDay());//在这里体现“位”操作
}
System.out.println("都没人在的是"+days);
} public static void getEveryDay(Worker[] work){//哪天都来人
Set<Day> days = EnumSet.allOf(Day.class);
for(Worker w:work){
days.retainAll(w.getAvalibleDay());//在这里体现“位”操作
}
System.out.println("都有人在的是"+days);
} Worker[] workers = new Worker[]{
new Worker("张三", EnumSet.of(
Day.TUESDAY, Day.WEDNESDAY, Day.FRIDAY)),
new Worker("李四", EnumSet.of(
Day.TUESDAY, Day.THURSDAY, Day.SATURDAY)),
new Worker("王五", EnumSet.of(
Day.TUESDAY, Day.THURSDAY)),
};
MyTestMethod.getNoDay(workers);
MyTestMethod.getEveryDay(workers); //输出
//都没人在的是[MONDAY, SUNDAY]
//都有人在的是[TUESDAY]

 

用接口模拟可扩展Enum

设计枚举的时候最好不要设计可扩展性,如果实在要设计,可以使用接口的方式实现。

public interface OperationInterface {
double apply(double x,double y);
} public enum OperationEnum implements OperationInterface {//可以设计很多个implements OperationInterface的枚举,实现枚举的变相扩展
PLUS("+") {
@Override
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
@Override
public double apply(double x, double y) {
return x - y;
}
};
private final String symbol; OperationEnum(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
/**
* @Description:
* @author: shengzhizhi
* @modifier:
* @date: 2018年8月20日 下午5:58:21
*/
return this.symbol;
} } public class TestEnumForImplement { public static void main(String[] args) {
double d1 = 1.2;
double d2 = 2.2;
say(Arrays.asList(OperationEnum.values()),d1,d2);
} public static void say(Collection<? extends OperationInterface> opSet, double x, double y) {
for (OperationInterface e : opSet) {
System.out.printf("the methos is %s, result is %f%n", e, e.apply(x, y));
}
}
}

Effective Java (ENUM篇)的更多相关文章

  1. [Effective Java] 创建和销毁对象篇

    [Effective Java] 创建和销毁对象篇 1. 优先考虑用静态工厂方法代替构造器 优点: - 静态工厂方法相比于构造器,它们有名称 - 不需要每次在使用的时候创建一个对象 - 可以返回原返回 ...

  2. Effective Java 第二版 Enum

    /** * Effective Java 第二版 * 第30条:用enum代替int常量 */ import java.util.HashMap;import java.util.Map; publi ...

  3. Effective Java通俗理解(持续更新)

    这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...

  4. Effective Java通俗理解(下)

    Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...

  5. effective java笔记之单例模式与序列化

    单例模式:"一个类有且仅有一个实例,并且自行实例化向整个系统提供." 单例模式实现方式有多种,例如懒汉模式(等用到时候再实例化),饿汉模式(类加载时就实例化)等,这里用饿汉模式方法 ...

  6. Effective Java通俗理解(上)

    这篇博客是Java经典书籍<Effective Java(第二版)>的读书笔记,此书共有78条关于编写高质量Java代码的建议,我会试着逐一对其进行更为通俗易懂地讲解,故此篇博客的更新大约 ...

  7. 《Effective Java》读书笔记(一)之创建和销毁对象

    最近在研读<Effective Java>一书,读书不做点笔记,感觉很容易就忘掉,于是用本篇博客来记录阅读此书的笔记. 郑重声明: 由于是<Effective Java>一书的 ...

  8. 如何创建和销毁对象(Effective Java 第二章)

    最近有在看Effective Java,特此记录下自己所体会到的东西,写篇博文会更加的加深印象,如有理解有误的地方,希望不吝赐教. 这章主题主要是介绍:何时以及如何创建对象,何时以及如何避免创建对象, ...

  9. 简单认识java enum枚举

    什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...

  10. Effective Java —— 用私有构造器或枚举类型强化单例属性

    本文参考 本篇文章参考自<Effective Java>第三版第三条"Enforce the singleton property with a private construc ...

随机推荐

  1. spark app

    使用Spark和Scala分析Apache访问日志 http://www.jdon.com/bigdata/analyzing-apache-access-logs-files-spark-scala ...

  2. appium+python+unittest+HTMLRunner编写UI自动化测试集

    简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以py ...

  3. raw_input 和input 区别

    raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收).而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它 ...

  4. mysql 时间戳转换 、cnd、dns 通俗理解

  5. java类的设计原则

    1.内聚性 类应该描述一个单一的实体,所有的类操作应该在逻辑上相互配合,支持一个连贯性的目标.例如:学生和教职工属于不同的实体,应该定义两个类. 2.一致性 要遵循一定的设计风格和命名习惯.给类.方法 ...

  6. 安装sql 2008步骤以及所遇到的问题

    下载网址:http://www.xiazaiba.com/html/4610.html 安装步骤: 1.  在Windows7操作系统系,启动Microsoft SQL 2008安装程序后,系统兼容性 ...

  7. org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'list' in 'c

     org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'list' in ' ...

  8. ssm的web项目,浏览器使用get方法传递中文参数时,出现乱码

    ssm的web项目,浏览器使用get链接传递的为中文参数时,出现乱码 做搜索功能时,搜索手机,那么浏览器传递的参数为中文参数“手机”,但传递的默认编码格式为iso-8859-1,所以传到后台时,是乱码 ...

  9. SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用

    pq_distribute提示通常被用于提升数据仓库中分区表间的连接操作性能. pq_distribute提示允许你确定参与连接的表数据行在生产和消费并行查询服务进程间如何分配. pq_distrib ...

  10. easyUI的form表单重复提交处理

    1. 问题 生产环境出现过新增用户提交, 入库两条重复数据的情况; 但是我查看代码, 页面做了校验, 后台插入数据也做了校验;  出现这种几率的事件的非常小的, 但是还是会碰到, 客户会对我们的产品产 ...