博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

Enum 类

这是所有 Java 语言枚举类型的公共基本类。

public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable

构造方法

protected Enum(String name, int ordinal) 单独的构造方法。

  • 程序员无法调用此构造方法。
  • 该构造方法用于由响应枚举类型声明的编译器发出的代码。
  • 参数 name - - 此枚举常量的名称,它是用来声明该常量的标识符。
  • 参数 ordinal - - 枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

静态方法

static <T extends Enum<T>>  T  valueOf(Class<T> enumType, String name)

返回带指定名称的指定枚举类型的枚举常量。

  • 名称必须与在此类型中声明枚举常量所用的标识符完全匹配。不允许使用额外的空白字符。
  • 参数:enumType - 要从中返回常量的枚举类型的 Class 对象
  • 参数:name - 要返回的常量名称
  • 抛出:
    • IllegalArgumentException - 如果指定枚举类型不包含指定名称的常量,或者指定类对象不表示枚举类型
    • NullPointerException - 如果 enumType 或 name 为空

另外两个没有在API文档中出现但实际存在的静态方法:

static T valueOf(String name) //返回带指定名称的当前枚举类型的枚举常量。
static T[] values() //返回当前枚举类型的枚举常量数组。

新增的方法

Class<E>  getDeclaringClass()

返回与此枚举常量的枚举类型相对应的 Class 对象。

  • 当且仅当 e1.getDeclaringClass() == e2.getDeclaringClass() 时,两个枚举常量 e1 和 e2 的枚举类型才相同。
  • 由该方法返回的值不同于由 Object.getClass() 方法返回的值, Object.getClass() 方法用于带有特定常量的类主体的枚举常量。
String  name()

返回此枚举常量的名称,在其枚举声明中对其进行声明。

  • 与此方法相比,大多数程序员应该优先考虑使用 toString() 方法,因为 toString 方法返回更加用户友好的名称。
  • 该方法主要设计用于特殊情形,其正确性取决于获取正确的名称,其名称不会随版本的改变而改变。
int  ordinal()

返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。 
大多数程序员不会使用此方法。它被设计用于复杂的基于枚举的数据结构,比如 EnumSet 和 EnumMap。

Object 中的方法

int  compareTo(E o)

比较此枚举与指定对象的顺序。

  • 在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。
  • 枚举常量只能与相同枚举类型的其他枚举常量进行比较。
  • 该方法实现的自然顺序就是声明常量的顺序。
boolean  equals(Object other) //当指定对象等于此枚举常量时,返回 true。
protected  void  finalize()

枚举类不能有 finalize 方法。 
类 Object 中的 finalize 方法的作用是:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

int  hashCode() //返回枚举常量的哈希码。
String  toString()

返回枚举常量的名称,它包含在声明中。

  • 它包含在声明中。可以重写此方法,虽然一般来说没有必要。
  • 当存在更加“程序员友好的”字符串形式时,应该使用枚举类型重写此方法。
protected Object clone() throws CloneNotSupportedException

返回此实例的一个副本。

  • 如果对象的类不支持 Cloneable 接口,则抛出 CloneNotSupportedException。这可保证永远不会复制枚举,这对于保留其“单元素”状态是必需的。
  • 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法复制某个实例。

关键字 enum

创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类。枚举类型符合通用模式 Class Enum<E extends Enum>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。

enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个 class 文件。该 class 文件经过反编译可以看到实际上是生成了一个类,该类继承了 java.lang.Enum。比如:

public enum EnumTest {
MON, TUE;
}

首先编译一下(使用 java 命令),然后直接读取编译后的 EnumTest.class 文件,内容如下:

public enum EnumTest {
MON,
TUE,
private EnumTest() {
}
}

经过反编译之后得到的内容如下:

javap EnumTest.class
Compiled from "EnumTest.java"
public final class test.EnumTest extends java.lang.Enum<test.EnumTest> { //继承自 Enum
public static final test.EnumTest MON;
public static final test.EnumTest TUE;
public static test.EnumTest[] values(); //多了一个 values 方法
public static test.EnumTest valueOf(java.lang.String); //重载了一个 valueOf 方法
static {};
}

所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。

总结:

可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum (单一继承)。

测试代码

最简单的定义形式

public enum EnumTest {
MON, TUE, WED, THU, FRI, SAT, SUN; //这段代码实际上调用了7次构造方法 Enum(String name, int ordinal):
}

详细使用案例

给 enum 自定义属性和方法:

enum MyEnum {
MON("bqt1", 1), TUE("bqt2", 2) {
@Override
public String tips() {
return "黑色星期二";
}
},
WED("bqt3", 3) {
@Override
public boolean isBoy() {
return true;
}
},
THU("bqt1", 1); // 成员变量
public String key;
public int value; // 构造方法
MyEnum(String key, int value) {
this.key = key;
this.value = value;
} public String tips() {
return "Nothing";
} public boolean isBoy() {
return false;
}
}

测试

System.out.println(MyEnum.MON instanceof Enum); // true
System.out.println(MyEnum.valueOf("MON") + " " + Enum.valueOf(MyEnum.class, "MON")); // MON MON //常用方法
System.out.println(MyEnum.MON.name() + " " + MyEnum.MON.toString()); // MON MON
System.out.println(MyEnum.MON.ordinal() + " " + MyEnum.MON.getDeclaringClass()); // 0 class MyEnum
System.out.println(MyEnum.MON.equals(MyEnum.THU) + " " + MyEnum.MON.compareTo(MyEnum.THU)); // false -3 //给 enum 自定义属性和方法
System.out.println(MyEnum.MON.key + " " + MyEnum.MON.value); // bqt1 1
System.out.println(MyEnum.MON.tips() + " " + MyEnum.TUE.tips()); // Nothing 黑色星期二
System.out.println(MyEnum.MON.isBoy() + " " + MyEnum.WED.isBoy()); // false true //遍历
MyEnum[] array = MyEnum.values();
System.out.println(Arrays.toString(array)); // [MON, TUE, WED, THU]
for (MyEnum myEnum : MyEnum.values()) {
System.out.print(myEnum.toString() + " "); // MON TUE WED THU
}

在 switch 语句中使用 enum

比如上面的 MyEnum ,如果按下面形式去使用:

MyEnum myEnum = MyEnum.TUE;
switch (myEnum) {
case MyEnum.MON:
break;
case MyEnum.TUE:
break;
default:
break;
}

此时会提示:

an enum switch case label must be the unqualified name of an enumeration constant

意思是: 枚举的 switch case 标签必须为枚举常量的非限定名称。

什么意思呢?意思就是 case 语句中只能写枚举类定义的变量名称,不能加类名。

正常代码如下:

MyEnum myEnum = MyEnum.TUE;
switch (myEnum) {
case MON:
break;
case TUE:
break;
default:
break;
}

为什么必须这么写呢?

我们看 官方文档 中对 switch 语句的描述

  • If the type of the switch statement’s Expression is an enum type, then every case constant associated with the switch statement must be an enum constant of that type.
  • Every case label has a case constant, which is either a constant expression or the name of an enum constant.
  • If the type of the switch statement's语句 Expression is an enum type, then every case constant associated with关联的 the switch statement must be an enum constant of that type.
  • If the switch statement's Expression is of a reference type引用类型, that is, String or a boxed primitive type or an enum type, then an exception will be thrown will occur if the Expression evaluates to null at run time.
  • A Java compiler is encouraged鼓励 (but not required) to provide a warning if a switch on an enum-valued expression lacks缺少 a default label and lacks case labels for one or more of the enum's constants. Such a switch will silently do nothing if the expression evaluates to one of the missing constants.

里面也貌似并没有细说为何不能带限定名。

2018-7-16

构建-4 dependencies 依赖管理的更多相关文章

  1. 从初识Maven到使用Maven进行依赖管理和项目构建

    前些天就安装了Maven,以备自己以后整合项目用,尤其是我们的ssh,ssm项目.想必好多人在开始的时候并不清楚Maven是什么,它能够帮助我们干什么. 所以在学习Maven之前我们一定要知道它是什么 ...

  2. Java构建工具:如何用Maven,Gradle和Ant+Ivy进行依赖管理

    原文来自:https://zeroturnaround.com/rebellabs/java-build-tools-how-dependency-management-works-with-mave ...

  3. Maven01——简介、安装配置、入门程序、项目构建和依赖管理

    1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目的 Svn eclipse   maven量级 1.2 Maven好处 同 ...

  4. 着重基础之—构建工具—Maven的依赖管理

    着重基础之—构建工具—Maven的依赖管理 项目构建利器Maven给我们开发人员带来了极大的便利,从繁琐的jar包管理中脱身的程序员终于可以有时间再进入另一个坑了. 我今天要给大家分享的内容是我在实际 ...

  5. maven——项目构建和依赖管理工具

    apache maven是一个用于项目构建和依赖管理的工具. 添加archetype https://repo1.maven.org/maven2/archetype-catalog.xml 更改本地 ...

  6. 使用maven-pom进行依赖管理与自动构建

    使用maven-pom进行依赖管理与自动构建 span.kw { color: #007020; font-weight: bold; } /* Keyword */ code > span.d ...

  7. 适合Linux嵌入式项目的代码构建与依赖管理工具——cazel

    前言 我们知道,现在有很多流行的优秀代码构建工具,如CMake.jetkins.bazel等.这些不同的构建工具在其应用的领域起到了举足轻重的作用. 但是,如果仔细研究就会发现,在嵌入式领域,构建工具 ...

  8. Gradle Maven 依赖管理

    仓库管理简介 本质上说,仓库是一种存放依赖的容器,每一个项目都具备一个或多个仓库. Gradle支持以下仓库格式: Ivy仓库 Maven仓库 Flat directory仓库 我们来看一下,对于每一 ...

  9. Java Gradle入门指南之依赖管理(添加依赖、仓库、版本冲突)

        开发任何软件,如何管理依赖是一道绕不过去的坎,软件开发过程中,我们往往会使用这样那样的第三方库,这个时候,一个好的依赖管理就显得尤为重要了.作为一个自动构建工作,Gradle对依赖管理有着很好 ...

随机推荐

  1. CentOS 7 上安装vim 解決 centos -bash: vim: command not found

    用CentOS上使用vim竟然用不了,报错没有该命令 centos -bash: vim: command not found 那么如何安裝 vim 呢? ---------------------- ...

  2. 【原】Maven解决jar冲突调试步骤:第三方组件引用不符合要求的javassit导致的相关异常

    [环境参数]开发框架:Spring + MyBatis + SpringMVC + KettleJDK版本:1.8.0_91javassist依赖版本:javassit-3.12.1.GA [障碍再现 ...

  3. 使用 IntraWeb (23) - 基本控件之 TIWTimer、TIWProgressBar、TIWProgressIndicator、TIWTimeEdit

    TIWTimer //和 TTimer 没多大区别, 它的默认事件现在是异步的(OnAsyncTimer), 在网络上使用 OnTimer 肯定是非常糟糕的 TIWProgressBar //进度条 ...

  4. CentOS 7下软阵列的创建

    硬阵列和软阵列没有什么可比性,毕竟应用的场景不一样,比如硬阵列性能强劲,有额外的内存支持缓存使其更快,但也有缺点,以硬盘为个数,且如果其中某个硬盘的容量不齐,那么会以最小的容量为准,体现出硬阵列的不灵 ...

  5. CAT架构的应用与实践 IT大咖说 - 大咖干货,不再错过

    CAT架构的应用与实践 IT大咖说 - 大咖干货,不再错过 http://www.itdks.com/dakashuo/new/dakalive/detail/594

  6. PHP上传文件大小限制的问题(转)

      在用PHP进行文件上传的操作中,需要知道怎么控制上传文件大小的设置,而文件可传大小是受到多种因素制约的,现总结如下:1.php.ini:upload_max_filesize 所上传的文件的最大大 ...

  7. OpenOCD 0.9.0 release

    OpenOCD 0.9.0 release May 18th, 2015 I’m happy to announce the release of OpenOCD version 0.9.0, fin ...

  8. 手把手教你使用C#操作SQLite数据库,新建数据库,创建表,插入,查询,删除,运算符,like

    目录: 一.新建项目,添加引用 二.创建数据库 三.创建表 四.插入数据  五.查询数据  六.删除数据  七.运算符 八.like语句 我的环境配置:windows 64,VS,SQLite(点击下 ...

  9. C#中POST数据和接收的几种方式

    POST方式提交数据,一种众所周知的方式: html页面中使用form表单提交,接收方式,使用Request.Form[""]或Request.QueryString[" ...

  10. ASP.NET MVC下实现前端视图页的Session

    在ASP.NET MVC的控制器中可以实现Session处理.如果要在前端视图页实现Session该如何做呢?可以使用window.sessionStorage来做. AlexChittock用jQu ...