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 ...
随机推荐
- core dump 是什么意思?
core dump,翻译过来讲,就是核心转储.大致上就是指,如果由于应用错误,如浮点异常.指令异常等,操作系统将会转入内核的异常处理,向对应的进程发送特定的信号(SIGNAL),如果进程中没有对这些信 ...
- 前端开发必备!Emmet语法
使用方法 emmet的使用方法也非常简单,以sublime text为例,直接在编辑器中输入HTML或CSS的代码的缩写,然后按tab键就可以拓展为完整的代码片段.(如果与已有的快捷键有冲突的话,可以 ...
- poj 1270(toposort)
http://poj.org/problem?id=1270 题意:给一个字符串,然后再给你一些规则,要你把所有的情况都按照字典序进行输出. 思路:很明显这肯定要用到拓扑排序,当然看到discuss里 ...
- NSString相关操作
//创建一个字符串对象 NSString * str_1 = @"Hello"; //字面量方法 ; NSString * str_2 = [NSString stringWith ...
- mac tomcat https
一.HTTPS的基本工作原理: HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息.TLS/SSL协议不仅仅是一套加密传输的协议 ...
- iOS //清除本地缓存
//清除本地缓存 -(void)clearCache{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT ...
- c语言中遇到“警告: the `gets' function is dangerous and should not be used.”的解决办法
写于2016年12月1日. 在用c的库函数gets(str)时,编译出现该提示.原因在于linux下gcc不支持gets命令,要换成fgets(arr,size,stdin).
- 移动端touchstart、touchmove事件的基本使用
在pc端,我们通常使用$(window).scroll()事件来监听元素的位置,来做一些入场动效,如: $(window).scroll(function(){ var panel3Move = do ...
- xml dtd 定义元素
ANY 如果需要定义某个元素的值可以是任意类型,可采用如下语法 <!ELEMENT 元素名 ANY> DTD必须定义XML文档中允许出现的所有元素,所以下面这样是不行的,因为<hel ...
- input上传按钮美化
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...