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 枚举的更多相关文章

  1. Java核心 --- 枚举

    Java核心 --- 枚举 枚举把显示的变量与逻辑的数字绑定在一起在编译的时候,就会发现数据不合法也起到了使程序更加易读,规范代码的作用 一.用普通类的方式实现枚举 新建一个终态类Season,把构造 ...

  2. 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)

    写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...

  3. java的枚举2

    首先先理解一下java中枚举的本质. java的世界中一切皆是类,下面通过一个例子解释一下enum的本质: package cn.xnchall.enumeration; public class G ...

  4. Java开发知识之Java的枚举

    Java开发知识之Java的枚举 一丶什么是枚举 枚举可以理解为就是常量,在Java中我们定义常量.都是用 final语句. C++中都是用const关键字. 枚举跟C++概念都是一样的.就是特定的常 ...

  5. Java学习--枚举

    枚举类型enum,地位等同于class,interface 使用enum定义的枚举类型,也是一种变量类型,可用于声明变量 枚举的一些特征 1.它不能有public的构造函数,这样做可以保证客户代码没有 ...

  6. Java中枚举的使用

    Java中枚举其实就是静态常量,今天发现枚举里面其实还能加方法,学习了下, 代码如下: package org.pine.test; import java.util.HashMap; import ...

  7. 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题

    原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...

  8. Java中枚举的写法和用法

            在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法         关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...

  9. java基础---->Java中枚举的使用(一)

    这里介绍一下java中关于枚举的使用. java中枚举的使用 一.枚举中可以定义方法 参照于TimeUnit的使用,TimeUnit.MILLISECONDS.sleep(1000); LoveUti ...

随机推荐

  1. Python日志logging

    logging 用于便捷记录日志且线程安全的模块 1.单文件日志 import logging logging.basicConfig(filename='log.log', format='%(as ...

  2. bzoj3439 trie+可持久化线段树

    挺好想的 trie建树后,按dfn序建可持久化 注意:计数变量多的题目一定要注意检查会不会用的时候搞混了 #include <cstdio> #include <cstdlib> ...

  3. TFS二次开发系列:三、TFS二次开发的第一个实例

    首先我们需要认识TFS二次开发的两大获取服务对象的类. 他们分别为TfsConfigurationServer和TfsTeamProjectCollection,他们的不同点在于可以获取不同的TFS ...

  4. 用netbeans和xdebug调试php的配置

    xdebug的chrome.firefox插件 chrome:Xdebug helper firefox:easy Xdebug ----------------------------------- ...

  5. 2.goldengate日常维护命令(转载)

    goldengate日常维护命令 发表于 2013 年 7 月 4 日 由 Asysdba 1.查看进程状态 GGSCI (PONY) 2> info all 2.查看进程详细状态,有助于排错 ...

  6. 修改vim的主题风格

    参考网站:https://github.com/yangyangwithgnu/use_vim_as_ide#0.1 molokai源码:https://github.com/tomasr/molok ...

  7. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  8. System.Windows.Application.Current.Dispatcher.BeginInvoke

    System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>                        ...

  9. Linux琐碎

    本周接触Linux的内容: 1.netstat -tanlp 显示监听的所有端口并且不解析端口为属于哪个进程 history | grep cmd 从命令历史中找到需要的命令 2. scp命令的使用: ...

  10. iOS Safari 中click点击事件失效的解决办法

    问题起因: 在微信公众号开发(微站)过程中用jquery的live方法绑定的click事件点击无效(不能执行) 问题描述 当使用委托给一个元素添加click事件时,如果事件是委托到 document  ...