Enum与最佳単例设计

1 枚举基础

自定义一个枚举类很简单, 不过类型关键字是 enum, 不是 class, 也不是 interface.
public enum Action {
  UP, DOWN, LEFT, RIGHT
}

自定义的 Action枚举 本质上还是一个 class, 反编译可以看到如下定义:
public final class Action extends Enum {...}

enum关键字 定义了特殊的类, 继承 java.lang.Enum, 由编译程序处理, 我们直接写类继承 Enum类 会被编译程序拒绝. 有必要了解下 java.lang.Enum类.

Enum 是个抽象类, 无法直接实例化.
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
  private final String name;
  private final int ordinal;
  protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
  }
...
}
我们定义的 Action, 会继承这个 Enum, 并且四个枚举成员都将成为 static final 的 Action实例:
private Action(String s, int i){
  super(s, i);
}
public static final Action UP; //其他成员略
static{
  UP = new Action("UP", 0);
}

可以看出, Enum 的 name 记录了枚举成员的字符串名称, ordinal 则记录了枚举成员的加入顺序, Enum成员的排序和switch语法, 都是利用了 ordinal() 取得 int 值.
ordinal 的值是枚举成员定义的顺序(由0开始), 如果不想要这个顺序, 可以加入 int 字段来主动编号:

  DOWN(2), UP(1), RIGHT(4), LEFT(3);
  private int number;
  private Action(int number){
    this.number = number;
  }

值得注意的是, 我们向上面这样加入实例变量, 重写私有构造, 最后都会编译程序作为产生真的构造函数参考之用, 实际反编译会变成这样:
private Action(String s, int i, int number){
  super(s, i);
  this.number = number;
}
public static final DOWN; //其他成员略
...
static{
  DOWN = new Action("DOWN", 0, 2);
  ...
}
......

枚举成员, 在 JVM 中只会存在单一实例. //static final

--------------------------------------------------------------------------------
2 最佳単例设计

枚举类的特点, 决定了其在单例设计使用上的天然优势.
Joshua Bloch大神说过: 单元素的枚举类型已经成为实现Singleton的最佳方法.
 public enum EnumSingleton {
  INSTANCE;
  public EnumSingleton getInstance(){
    return INSTANCE;
  }
 }

优点:
写法简单优雅; 线程安全; 可应对反射攻击; 序列化支持..
缺点:
因为已经继承了 Enum, 所以不能再继承了.

参考:
<<JDK7学习笔记>>林信良
http://www.importnew.com/24272.html
http://www.runoob.com/design-pattern/singleton-pattern.html
http://www.cnblogs.com/chiclee/p/9097772.html
https://www.cnblogs.com/lanxuezaipiao/p/3369962.html

原文地址:https://www.cnblogs.com/noodlerkun/p/10306660.html

时间: 2024-08-03 04:51:47

Enum与最佳単例设计的相关文章

Java设计模式中的单例设计

/** * 单例设计模式 * 应用场合:只需要一个对象的 * 作用:保证整个应用程序中某个实例有且只有一个 * 类型有:饿汉模式.懒汉模式 * 下面的例子是一个饿汉模式的例子 */ class SingleDemo { // 1.将构造方法私有化,不允许外部直接创建使用 private SingleDemo() {} // 2.创建类的唯一实例,使用private static修饰 private static SingleDemo instance = new SingleDemo(); //

不得不说--自动化测试元素定位与用例设计

关于自动化测试,经常被问到元素的定位 与 如何设计用例. 很多时间我也帮不了你解决实际的问题,只能从个人脚本谈谈如何看待这些问题. 不得不说之元素定位 虽然,本章写了十几篇文章来讲元素的定位与操作,对于碰到的一些常见功能,如何通过技巧来定位它们,但是在实际的自动化脚本开发中,不管是新手还是具有一定经验的老手,我们面临最多的问题仍然是元素的定位问题. 有时间元素定位非常简单,例如,我们只要知道这个元素有的id和name 就可以轻松的来定位到它:有时间元素的定位却非常的令人非常头疼,尽管我们用尽了所

Spring容器-ApplicationContext的单例设计

Spring容器-ApplicationContext的单例设计 每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会重新加载配置文件,并且这个创建的容器对象持有一个所有singleton类型bean的map集合,从而实现单例,而且这个map对象的生命周期和容器对象的生命周期是一样的 如果我们每次都通过new一个容器对象,那么每次都要重新加载配置文件,都要重新生成这个singleton bean的集合,这样所谓的单例就

接口测试原理、流程及用例设计

接口测试的原理是模拟客户端向服务器发送报文请求,服务器接收请求报文后对相应的报文做处理并向客户端返回应答,客户端接收应答的一个过程. 接口测试流程: 模拟客户端连接服务器(服务器提供的端口是否可访问) ↓ 客户端发送报文请求 ↓ 服务器端接收请求并做处理 ↓ 检查返回的预期结果并与实际结果对比 ↓ 结束 接口测试用例设计: 接口测试的主要测试对象是接口,但随着系统复杂度越来越高,接口越来越多,完全覆盖所有接口是很难的一件事情,且实际过程中任意内部接口的变动都可能导致我们测试用例的不可用. 所以通

基于技术方案的用例设计

上一篇介绍了基于需求文档的用例设计,主要是运用了黑盒测试的用例设计方法.之前提到用例在整个项目过程中是动态更新,逐步完善的,经过了需求评审的用例编写后,项目会进行技术方案评审,评审结束后,需要基于技术方案对用例进行一次补充完善. 我仍然以登录为例,由于每个开发设计的方案不同,在此列一个大致的通用方案,基于该方案做用例设计,精髓会了,其他的融会贯通. 登录成功的时序图如下: 登录失败的时序图如下: 分析时序图,步骤比较清晰,客户端的主要工作分为几部分: 1.绘制登录界面(UILabel.UIBut

软件测试 —— 用例设计3(其他)

错误推测方法: 一.    方法简介 1.         定义:基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法. 2.         错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例. 1)        例如, 输入数据和输出数据为0的情况:输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况.可选择这些情况下的例子作为测试用例. 2)        例如,前面例子中成绩报告的程序,采用错误推

【小白的java成长系列】——构造方法私有化(单例设计)

有了解过spring框架的童鞋们就知道,spring的bean默认是什么形式呀?---单例形式的. 问:那什么叫做单例?单例其实就是Singleton,顾名思义就是只有单个的实例对象操作. 那为什么要使用单例呢? 至于这个问题,后面再做解释,我们先看代码: package me.javen.oop; public class SingletonDemo { public static void main(String[] args) { Singleton singleton1 = Single

基于需求文档(PRD)的功能用例设计

上一篇我讲了在项目运行过程中,用例是需要动态更新的.接下来我将结合实例(移动app)讲解在不同的阶段如何设计用例. 需求文档(PRD)主要讲述app的某个模块有什么功能,每一项功能的页面展示.页面操作有哪些,不同操作之间的关系是什么.基于PRD的用例设计是使用黑盒测试方法,而我平时主要使用了等价类划分.边界值分析法.状态转换测试.场景测试,操作实践时偏好于将模块分成页面展现.页面操作.接口.异常流,在每一个子项里运用黑盒测试方法进行设计. 以移动app的登录为例,大致需求如下图: 一.验证登录弹

新增和修改页面的用例设计和Bug提交

问题: 新增页面和修改页面,基本上输入框都一样,那比如同一个输入框的用例设计: 1. 写了新增页面的用例,修改页面对该输入框还有再写一遍用例的必要吗? 2. 执行用例时,新增页面验证了必填项,长度,数据类型,修改页面还要再验证一遍吗? 3. 提交Bug时,新增和修改页面的同一个输入框都出现了Bug,是只提交一个还是新增和修改各提一个. 参考答案: 我们写用例最容易落入一个误区,就是为了写用例而写用例.实际上写用例最主要目的是分析系统,如果系统业务复杂,用例分析与设计就很重要,如果很简单的功能不写