Java 005 枚举
public final String name()
Returns the name of this enum constant, exactly as declared in its enum declaration. Most programmers should use the toString() method in preference to this one, as the toString method may return a more user-friendly name. This method is designed primarily for use in specialized situations where correctness depends on getting the exact name, which will not vary from release to release.
public String toString()
Returns the name of this enum constant, as contained in the declaration. This method may be overridden, though it typically isn't necessary or desirable. An enum type should override this method when a more "programmer-friendly" string form exists.
System.out.println(Week.Monday) ---> Week.Monday 默认调用toString()方法
枚举概述:就是有有限值的集合或类。
是指将变量的值一一列出来, 变量的值只限于列举出来的值得范围。 举例: 一周7天, 一年12个月等。
回想单列设计模式: 单例类是一个类只有一个实例。
那么多例类就是一个类有多个实例, 但不是无限个数的实例, 而是有限个数的实例。 这才能是枚举类。
通过自定义一个枚举类:
// 第一版:Simple
public class UD_Enum {
public static final UD_Enum FRONT = new UD_Enum();
public static final UD_Enum BEHIND = new UD_Enum();
public static final UD_Enum LEFT = new UD_Enum();
public static final UD_Enum RIGHT = new UD_Enum(); private UD_Enum() { }
} // 第二版:Medium
public class UD_Enum2 {
public static final UD_Enum2 FRONT = new UD_Enum2("FRONT");
public static final UD_Enum2 BEHIND = new UD_Enum2("BEHIND");
public static final UD_Enum2 LEFT = new UD_Enum2("LEFT");
public static final UD_Enum2 RIGHT = new UD_Enum2("RIGHT"); private String name; public String getName() {
return this.name;
} private UD_Enum2(String name) {
this.name = name;
} private UD_Enum2() {
}
} // 第三版: Complex
public abstract class UD_Enum3 {
public static final UD_Enum3 FRONT = new UD_Enum3("FRONT") {
@Override
public void show() {
System.out.println("this is front");
}
};
public static final UD_Enum3 BEHIND = new UD_Enum3("BEHIND") {
@Override
public void show() {
System.out.println("this is behind");
}
};
public static final UD_Enum3 LEFT = new UD_Enum3("LEFT") {
@Override
public void show() {
System.out.println("this is left");
}
};
public static final UD_Enum3 RIGHT = new UD_Enum3("RIGHT") {
@Override
public void show() {
System.out.println("this is right");
}
}; private String name; public String getName() {
return this.name;
} private UD_Enum3(String name) {
this.name = name;
} private UD_Enum3() {
} public abstract void show();
}
class EnumDemo {
public static void main(String[] args) {
System.out.println("-------------- User Defined Enum - Simple ----------------------");
UD_Enum ud1 = UD_Enum.BEHIND;
System.out.println(ud1); System.out.println("-------------- User Defined Enum - Medium ----------------------");
UD_Enum2 ud2 = UD_Enum2.LEFT;
System.out.println(ud2);
System.out.println(ud2.getName()); System.out.println("-------------- User Defined Enum - Implex ----------------------");
UD_Enum3 ud3 = UD_Enum3.RIGHT;
System.out.println(ud3);
System.out.println(ud3.getName());
ud3.show();
}
}
-- Console output ----
-------------- User Defined Enum - Simple ----------------------
com.java.test.UD_Enum@1db9742
-------------- User Defined Enum - Medium ----------------------
com.java.test.UD_Enum2@106d69c
LEFT
-------------- User Defined Enum - Implex ----------------------
com.java.test.UD_Enum3$4@52e922
RIGHT
this is right
发现自定义一个枚举类比较麻烦, 所以java就提供了枚举类供我们使用。
格式是: 只有枚举项的枚举类
public enum 枚举类名{
枚举项1, 枚举项2, 枚举项3.........;
}
class EnumUtil {
public static enum Browser {
CHROME,
IE,
FIREFOX,
HTMLUNIT
} /**
* ReportOptions.Client.name() -- 内置的方法, 返回自身的字符串值 比如 返回的是 Client
* 既然枚举类型提供了构造函数,我们可以通过构造函数和覆写toString 方法来实现。
* 首先给枚举类型增加构造方法,然后每个枚举类型的值通过构造函数传入对应的参数,
* 同时覆写toString 方法,在该方法中返回从构造函数中传入的参数,改造后的代码如下:
* @author LL-CC
*/
public static enum ReportOptions{
Client("Client Document Upload"),
Color("Report Color Upload"),
Position("Report Position Upload"); private String value;
private ReportOptions(String value){
this.value = value;
} public String toString() {
return this.value;
}
}
}
注意事项:
- 定义枚举类要用关键字Enum
- 所有枚举类都是Enum的子类
- 枚举类的第一行必须是枚举项, 最后一个枚举项的分号是可以省略的, 但是如果枚举类有其他的东西, 这个分号不能省略。 建议不要省略
- 枚举类也可以由构造函数, 但必须是private的, 它默认的也是private的。 枚举项的用法比较特殊, 枚举("")
- 枚举类也可以有抽象方法, 但是枚举项必须重写该方法
- 枚举在switch语句中的使用
public enum EnumComplex {
FRONT("front") {
@Override
public void show() {
System.out.println("I choose front");
}
},
BEHIND("behind") {
@Override
public void show() {
System.out.println("I choose behind");
}
},
LEFT("left") {
@Override
public void show() {
System.out.println("I choose left");
}
},
RIGHT("right") {
@Override
public void show() {
System.out.println("I choose right");
}
};
private String name; public String getName() {
return name;
} private EnumComplex(String name) {
this.name = name;
} public abstract void show();
} public static void main(String[] args) { System.out.println("-------------- Java Enum - Simple ----------------------");
EnumSimple ed1 = EnumSimple.RIGHT;
System.out.println(ed1); System.out.println("-------------- Java Enum - Complex ----------------------");
EnumComplex ed2 = EnumComplex.LEFT;
System.out.println(ed2);
System.out.println(ed2.getName());
ed2.show(); switch (ed2) {
case FRONT:
System.out.println("front");
break;
case BEHIND:
System.out.println("Behind");
break;
case LEFT:
System.out.println("left");
break;
case RIGHT:
System.out.println("right");
break;
}
}
枚举和类常量的对比:
1. 枚举类型是强类型的,从而保证了系统安全性。而以类的静态字段实现的类来替代枚举,不具有枚举的简单性和类型安全性。
把一个表示星期一到星期天的枚举类作为方法参数的时, 只能传递枚举项 限制了可以传递的范围 重点是限制 他给你类型 然后你去选择类型 这跟以前的判断方式肯定是不同的
枚举可以限定参数的个数,对调用者的行为能更加严格地进行控制。把一些运行期的参数检查放到了编译期,做到这点是一个很大的进步。 int 1-7 表示星期一到星期天, 作为参数传递时, 比如 0, 9 来调编译不会报错, 运行是就会出错。 枚举类型则可以将一个类型限制在可控制的范围内。
2. 枚举类型使代码更具可读性,理解清晰,易于维护。方便的代码机制。同时,如果枚举符号和对应的整数值发生变化,只需修改枚举定义即可,而不必在漫长的代码中进行修改。
表示星期1-7,你可以用int1-7,但是当你把它作为参数的时候,有时后你就给考虑传入0,8的情况.而且用数字表示还需要相应的注释和文档. 这个时候你定义个一个枚举,名字就叫字面就叫Monday , Tuesday ,....就行,直观,并且值可控.
如果要定义100个常量时候 你就知道枚举的好处了 包糖衣还是很有用的
静态常量其实是枚举模式的应用, 但它有很多缺点
* 类型不安全(静态常量可以随意增加使用或操作)
* 无命名空间,
* 脆弱(某常量值改变后客户端如果不编译热人仍能使用)
* 静态常量打印值为数字
* 不具有提示性
假如有一笔业务需要审核,审核状态分:未审核,审核中,审核通过,审核不通过。我们在程序里是否可以直接这么写:
if(state==1){//1代表未操作
//操作
}else{
//......
}
将状态标识直接写在代码里面(硬编码),只图一时方便,却是后患无穷,如果有一天你需要修改状态标识,用0代表未审核而不是1,你不得不将所有与该标识相关的代码都找出来一个个改,另外,在编码过程中,标识输入错误的概率是比较高的,一不小心把0输入成了10,虽然不会提示任何编译错误,但运行结果将是出乎人的意料的。
于是我们很快想到可以用常量代替:
public static final int UNAUDIT = 0;
相关判断代码则是:
if(state==CONSTANT.UNAUDIT){
//操作
}else{
//......
}
这段代码比硬编码更加健壮容易维护,但是仍然有不足之处。
1、UNAUDIT是编译期常量,如果其值被改变,那么使用方需要重新编译。
2、没有简便的方法获取标识代表的字符串描述。
于是我们用枚举类来代替常量。
public enum AuditState {
UNAUDIT(1),
AUDITING(2),
AUDIT_SUCCESS(3),
AUDIT_FAIL(4);
private final int statenum;
AuditState(int statenum){
this.statenum = statenum;
}
public int getStatenum() {
return statenum;
}
}
调用如下:
if (state == AuditState.UNAUDIT.getStatenum()) {
//AuditState.UNAUDIT.toString()获取字符串描述
System.out.println(AuditState.UNAUDIT.toString() + "标识是 "
+ AuditState.UNAUDIT.getStatenum());
} else {
//......
}
枚举类还有更加强大的功能,如添加字段,方法,还可以对他进行遍历访问
虽然枚举在很多方面都比接口常量和类常量好用,但是它有一点比不上接口常量和类常量的,就是继承,枚举类型是不能有继承的,也就是说一个枚举常量定义完毕后,除非修改重构,否则无法做扩展。
三、建议
在项目开发中,推荐使用枚举常量代替接口常量或类常量。
Java 005 枚举的更多相关文章
- Java核心 --- 枚举
Java核心 --- 枚举 枚举把显示的变量与逻辑的数字绑定在一起在编译的时候,就会发现数据不合法也起到了使程序更加易读,规范代码的作用 一.用普通类的方式实现枚举 新建一个终态类Season,把构造 ...
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...
- java的枚举2
首先先理解一下java中枚举的本质. java的世界中一切皆是类,下面通过一个例子解释一下enum的本质: package cn.xnchall.enumeration; public class G ...
- Java开发知识之Java的枚举
Java开发知识之Java的枚举 一丶什么是枚举 枚举可以理解为就是常量,在Java中我们定义常量.都是用 final语句. C++中都是用const关键字. 枚举跟C++概念都是一样的.就是特定的常 ...
- Java学习--枚举
枚举类型enum,地位等同于class,interface 使用enum定义的枚举类型,也是一种变量类型,可用于声明变量 枚举的一些特征 1.它不能有public的构造函数,这样做可以保证客户代码没有 ...
- Java中枚举的使用
Java中枚举其实就是静态常量,今天发现枚举里面其实还能加方法,学习了下, 代码如下: package org.pine.test; import java.util.HashMap; import ...
- 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题
原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...
- Java中枚举的写法和用法
在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法 关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...
- java基础---->Java中枚举的使用(一)
这里介绍一下java中关于枚举的使用. java中枚举的使用 一.枚举中可以定义方法 参照于TimeUnit的使用,TimeUnit.MILLISECONDS.sleep(1000); LoveUti ...
随机推荐
- python之路二
.pyc是个什么鬼? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存 ...
- C#夯实基础系列之字符串
string作为我们在编程当中用的最多的数据类型,同时又由于它的特殊性,怎么强调它的重要性都不为过,理解string的一些类型和存储机制,有助于我们写出正确且高效的代码. 一.string类型 1.s ...
- 医学CT图像特征提取算法(matlab实现)
本科毕设做的是医学CT图像特征提取方法研究,主要是肺部CT图像的特征提取.由于医学图像基本为灰度图像,因此我将特征主要分为三类:纹理特征,形态特征以及代数特征,每种特征都有对应的算法进行特征提取. 如 ...
- 解决ThinkPHP Call to a member function assign() on a non-object
<ignore_js_op> assign是tp模板输出变量的一个方法.没有object只能说没实例化...<ignore_js_op> 经过几番思索,终于发现了.原来是Act ...
- java9
1:StringBuffer(掌握) (1)用字符串做拼接,比较耗时并且也耗内存,而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了 一个字符串缓冲区类.StringBuffer供我们使 ...
- Spark集群部署
Spark是通用的基于内存计算的大数据框架,可以和hadoop生态系统很好的兼容,以下来部署Spark集群 集群环境:3节点 Master:bigdata1 Slaves:bigdata2,bigda ...
- Xtrabackup 安装使用
一 简介: Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB Hotbackup的一个很好的替代品.它能对Inno ...
- effective OC2.0 52阅读笔记(六 块与大中枢派发)
派发队列:dispatch_queue 操作队列:NSOperationQueue 组:dispathc_group_t 37 理解“块”这一概念 总结:块就是一个值,且自有其相关类型.块的强大之处 ...
- Scrapy003-项目流程
Scrapy003-项目流程 @(Spider)[POSTS] 前两篇文章我们了解到Scrapy的原理和安装的相关知识,这节就需要知道创建项目流程的小知识. 根据官方文档:http://scrapy- ...
- [jquery]添加行内容后根据下拉菜单选择内容对比之前已有选项,若有重置再提示
今天页面上一个添加列内容时,要对选择内容与之前已有选项内容作对比,防止用户重复选择内容 页面HTML代码 <ul class="list-group xj-list-NObor xj- ...