enum定以的类型就是一个类,一个类,一个类。重要的事情说三遍。用javac编译好enum类型后,会看到一个xxx.class文件,表明enum类型也是一个类。

本文中,我们用一个普通类去定义常量,模拟、对比用enum定义的常量,可以帮我们更容易理解enum类型是如何工作的。

enum跟class关键字一样,都是定义了一个类,只是这个类有点特殊,他有以下特点:

1. enum定义的这个类里边定义了一组常量(static final),并且每个常量的类型都是enum定义的这个类本身,并且这些常量都指向enum定义的这个类(或其子类)的对象(这些常量本身是对象的引用)。

2. 我们用普通类定义的的静态成员变量,长这样:

class Day{private int dayOfWeek;public static final Day Monday = new Day(0);public static final Day Tuestday= new Day(1);...Day(int day){this.dayOfWeek = day;}...
}

而用enum定义的类中定义的常量是下边这样:

enum Day{Monday, Tuesday, Wendesday ....;
}

其实他们是一回事。enum定义的类,里边的常量,你不需要显示的加上static final,然后用new创建一个对象赋给这些静态常量,这一切都由编译器给你做好。这就相当于一个语法糖。上边enum类里边定义的Monday, Tuesday, Wendesday等静态成员变量,实际上也会关联一个数字,只是不需要我们显式的通过new Day(0)或者Monday(0)来指定,编译器会帮我们搞定。

但有时候,我们希望用enum定义的常量,不仅仅是一个简单的常量,我们希望它关联更多的数据,这时我们会使用类似下边的语法,就是往enum定义的类里边添加更多的非静态成员变量:

enum Day{//每天上的课程private final String[] courses;Monday("语文","数学","英语"), Tuesday("体育","数学","英语"), Wendesday("化学","物理","英语") ....;CoursesOfDay(String ... courses){this.courses = courses;}
}

我们可以看到在这个例子中, Monday等常量不仅仅隐式的关联的一个整数变量,我们还显式的在这个类里边定义了一个数组,表示每天的课程表。如果你愿意,甚至还可以定义更多的非静态成员变量,这样每一个常量(实际上是一个该enum类的对象的引用)就可以关联到更多的数据。使用常量时,可以像这样:

System.out.println(Day.Monday.getCourses());

3. 这个用enum定义的类可以有多个非静态成员变量,但都必须是immutable的,也就是用final修饰。比如上边我们的courses变量用final修饰。

4. enum类的构造方法私有

5. enum定以的类默认拥有public的values()方法,返回的是一个数组,数组里边包含了所有我们之前定义的常量。

6. 这些常量的默认的toString()方法是打印跟常量同名的字符串,比如打印Day.Monday,输出结果就是Monday。可以覆写enum类型的toString()方法,改成自己期望的值,比如我们下边给出的示例toString()就打印了别的信息,不是常量名字本身。

7. enum类里边的静态常量不一定是该enum 类的对象,也可以是enum类的子类对象。比如下边代码中例子,每个static常量对象,都是一个重写了apply()抽象方法的子类对象。这样做的好处是防止以后添加新的常量时,没有添加该常量对应的动作。

下边的类似,参考了《effective java》中的一个例子,稍微有一点复杂。但是如果你能从类的角度去理解enum定义的类型,就很容易理解,而且enum定义的的确是类哦,只不过这个类里边有一些静态引用类型的常量,指向了一些类型本身的对象:

package enumeration;public class EnumDemo2 {public static void main(String[] args) {double x = 10.36;double y = 2.37;//使用enumOperation[] values = Operation.values();for (Operation operation : values) {System.out.println("x " + operation + " y = " + operation.apply(x, y));}System.out.println("*****************");//使用自定义普通类代替enumOperator1[] values1 = Operator1.values();for (Operator1 operation : values1) {System.out.println("x " + operation + " y = " + operation.apply(x, y));}}}//enum类型
enum Operation {//这里,常量指向的是子类的对象,这里使用了类似于匿名类的方式来给这些常量赋值。//Operation PLUS = new Operation(){ 覆写的方法 ... }PLUS("+") {public double apply(double x, double y) {return x + y;}},MINUS("-") {public double apply(double x, double y) {return x - y;}},MULTIPLY("*"){public double apply(double x, double y) {return x * y;}},DEVIDE("/"){public double apply(double x, double y) {return x / y;}};private final String opertator;Operation(String operator) {this.opertator = operator;}public abstract double apply(double x, double y);@Overridepublic String toString() {// TODO Auto-generated method stubreturn opertator;}}
//自定义类,可以实现跟enum类的类似的功能。
abstract class Operator1 {public static final Operator1 PLUS = new Operator1("+") {public double apply(double x, double y) {return x + y;}};public static final Operator1 MINUS = new Operator1("-") {public double apply(double x, double y) {return x - y;}};public static final Operator1 MULTIPLY = new Operator1("*") {public double apply(double x, double y) {return x * y;}};public static final Operator1 DIVIDE = new Operator1("/") {public double apply(double x, double y) {return x / y;}};private final String opertator;Operator1(String operator) {this.opertator = operator;}public abstract double apply(double x, double y);@Overridepublic String toString() {// TODO Auto-generated method stubreturn opertator;}public static Operator1 [] values() {Operator1 [] values = new Operator1[4];values[0] = PLUS;values[1] = MINUS;values[2] = MULTIPLY;values[3] = DIVIDE;return values;} }output:
-----------
x + y = 12.73
x - y = 7.989999999999999
x * y = 24.5532
x / y = 4.371308016877637
*****************
x + y = 12.73
x - y = 7.989999999999999
x * y = 24.5532
x / y = 4.371308016877637

从普通类的角度理解java的enum类型,用自定义类来模拟实现enum类的功能相关推荐

  1. 聊聊高并发(三十三)Java内存模型那些事(一)从一致性(Consistency)的角度理解Java内存模型

    可以说并发系统要解决的最核心问题之一就是一致性的问题,关于一致性的研究已经有几十年了,有大量的理论,算法支持.这篇说说一致性这个主题一些经常提到的概念,理清Java内存模型在其中的位置. 一致性问题更 ...

  2. java 类 null_深入理解java中的null“类型”

    本文研究的主要是java中的null"类型"的相关实例,具体介绍如下. 先给出一道简单的null相关的题目,引发我们对null的探讨,后面会根据官方语言手册对null"类 ...

  3. 【java】从进程角度理解java

    最近的华为事件给我们上了一课,业务是不能脱离基础的,我不给你芯片,就等于杀死了你. 编程语言这么多,真的有必要一个一个去学习吗?没有必要,但从业务角度来讲是有必要学习相关语言的,安卓开发就要学java ...

  4. JAVA类与对象构造方法,java基础-1-面向对象(1)-概念介绍与类、对象、构造方法...

    -------android培训.java培训.期待与您交流! ---------- 什么叫做面向对象? 想要了解什么事面向对象,我们首先需要了解,什么是面向过程. 所谓的面向过程,指的是在编程期间, ...

  5. Java中Person类型赋值_Java设计:定义一个Person类和它的子类Employee。Person类有姓名、地址、电话号码和电子邮箱,...

    匿名用户 1级 2017-04-26 回答 Person类: public class Person { private String address; private String name; pr ...

  6. 从分布式锁角度理解Java的synchronized关键字

    分布式锁 分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备 ...

  7. java的工厂类_深入理解Java的三种工厂模式

    一.简单工厂模式 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现.被创建实例的类型可以是接口.抽象类,也可以是具体的类 实现汽车接口 1 public interfaceCar {2 ...

  8. java接口是类型吗_JAVA中,接口到底是不是类

    从面向对象的角度来说,接口是一个超越了类的共性的描述,不能把它和类混为一谈 举个例子,现在有磁条卡和IC卡的两种银行卡,它们有很多共性,有卡号,基本是个长方形的薄片,有发卡行的标识等等等,这些共性可以 ...

  9. java中number类型能否相除_Java中 如果复数类成员是int型,怎么实现两个复数相除...

    (1) 复数类Complex 的属性有: RealPart :    int型,代表复数的实数部分 ImaginPart :  int型,代表复数的虚数部分 package applet; impor ...

最新文章

  1. 分享几个matlab的下载安装包吧,一周有效期,过期不候
  2. 面向对象编程(第五篇)
  3. 前端开发-4-HTML-tableform表单控制 标签
  4. 类QQ右下角弹出框(Qt)
  5. 笔记36 Spring Web Flow——配置
  6. 【译文练习】ReactiveCocoa概要:了解和使用RACCommand
  7. C#图像细化:Hilditch细化算法
  8. 智能对话训练师进阶本领:复杂对话流程处理
  9. FPGA学习记录_设计一个计数器
  10. Automating Android with Ant
  11. OPNsense用户手册-用户界面
  12. 计算机用户guest无法删除吗,Win7怎么删除Guest账户?
  13. android 6.0小游戏,宝宝汽车小游戏
  14. 宜家订单JSON_怎么评价宜家(IKEA)?
  15. 关于iOS 10从2017年1月1日起苹果不允许我们通过这个方法跳过ATS的方法
  16. 浅析配音的类别以及不同
  17. 系统动力学模型matlab仿真,MATLAB/Simulink动力学系统建模与仿真(带目录)_IT教程网...
  18. 嗨,年轻人,一定要做一个让自己不后悔的人哦!
  19. 学校初一模拟赛(2019.3.2)
  20. 3月25日助学作业答案

热门文章

  1. 基带0day漏洞可攻击数百万部华为手机
  2. python使用selenium打开chrome浏览器时带用户登录信息
  3. USACO-The Castle
  4. SAP 客户信贷重建一则
  5. win10无法登录到你的账户->注销->重启->桌面初始化(只剩回收站+默认浏览器)等一系列问题出现
  6. 超全荒地UE4素材网站整理
  7. python二级证书含金量排名_计算机二级证书的含金量不高?别小瞧,这些优势用处不小!...
  8. Android设备实时音视频传输有效方案
  9. 如何将多个文本文档合并到一个文档中?
  10. 怎么抓雷电模拟器的包_fiddler+雷电模拟器进行APP抓包(可抓HTTPS)