enum一个最不像class的class
java枚举类型是jdk5出现的.它的出现主要为了解决一些有特殊意义,已经确定的,长度不会改变的集合.

//月份描述
public class Month {
//月份名称
private final String name;
//月份天数
private final int days; //构造子,给出一个月份名称,默认天数31天
private Month(String name) {
this(name, 31);
}
//构造子,给出月份名称,月份天数
private Month(String name, int days) {
this.name = name;
this.days = days;
} /*
* 创建12个月份
* */
public static final Month JAN = new Month("January");
public static final Month FEB = new Month("February", 28);
public static final Month MAR = new Month("March");
public static final Month APR = new Month("April", 30);
public static final Month MAY = new Month("May");
public static final Month JUN = new Month("June", 30);
public static final Month JUL = new Month("July");
public static final Month AUG = new Month("August");
public static final Month SEP = new Month("September", 30);
public static final Month OCT = new Month("October");
public static final Month NOV = new Month("November", 30);
public static final Month DEC = new Month("December"); //获取月份名称
public String getName() {
return name;
} //获取月份值
public int getDays() {
return days;
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Month.JAN);//demo7.Month@1b6d3586
System.out.println(Month.JAN.getName());//January
System.out.println(Month.JAN.getDays());//
}
}

以上代码是创建了一个不可改变的月份表.内部实现就是一个在一个类中创建了12个实例对象.在客户端无需创建,直接获取没有月份的相关属性.以上写法在没有enum类型出现前,是最实用的写法.我们也可以看出

在enum类中,只提供查询方法,不提供修改方法.

在jdk1.5以后,创建enum类型就简单的多了.

public enum  EnumMonth {
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
}
public class Main {
public static void main(String[] args) {
System.out.println(EnumMonth.APR);//APR
}
}

这样声明一个只有12个月份的类是不是简单的多.而且我们可以看出.在客户端我们直接打印enum项打印的值,而不是地址值.那么这里边到底是怎么实现的呢?我们来看看反编译后的enum

public final class EnumMonth extends Enum
{ public static final EnumMonth JAN;
public static final EnumMonth FEB;
public static final EnumMonth MAR;
public static final EnumMonth APR;
public static final EnumMonth MAY;
public static final EnumMonth JUN;
public static final EnumMonth JUL;
public static final EnumMonth AUG;
public static final EnumMonth SEP;
public static final EnumMonth OCT;
public static final EnumMonth NOV;
public static final EnumMonth DEC;
private static final EnumMonth $VALUES[]; public static EnumMonth[] values()
{
return (EnumMonth[])$VALUES.clone();
} public static EnumMonth valueOf(String name)
{
return (EnumMonth)Enum.valueOf(demo7/EnumMonth, name);
} private EnumMonth(String s, int i)
{
super(s, i);
} static
{
JAN = new EnumMonth("JAN", 0);
FEB = new EnumMonth("FEB", 1);
MAR = new EnumMonth("MAR", 2);
APR = new EnumMonth("APR", 3);
MAY = new EnumMonth("MAY", 4);
JUN = new EnumMonth("JUN", 5);
JUL = new EnumMonth("JUL", 6);
AUG = new EnumMonth("AUG", 7);
SEP = new EnumMonth("SEP", 8);
OCT = new EnumMonth("OCT", 9);
NOV = new EnumMonth("NOV", 10);
DEC = new EnumMonth("DEC", 11);
$VALUES = (new EnumMonth[] {
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT,
NOV, DEC
});
}
}

从这个class文件我们能看出

EnumMonth继承自Enum.

EnumMonth有一个私有的两个参数的构造函数.

EnumMonth类中的枚举项也是自己通过实例化的构成的.

接下来我们来看看他的两个方法 valueOf() 和values()

public class Main {
public static void main(String[] args) {
System.out.println(EnumMonth.APR);//APR
EnumMonth apr = EnumMonth.valueOf("APR");
System.out.println(apr);//APR
EnumMonth[] values = EnumMonth.values();//JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC,
for (EnumMonth enumMonth : values){
System.out.print(enumMonth+",");
}
}
}

这不是我们的重点,现在我们要找它的toString()方法,可以让枚举项直接打印出值的,肯定只有toString().前往父类Enum寻找

所以现在可以得出结论.当我们创建一个枚举类时,实际上是有一个两个参数构造函数.默认传递的实参是我们的枚举项字符串和索引.

那么,如果我们覆盖双参数的构造函数呢?

public enum  DoubleEnumMonth {
JAN("JAN",0), FEB("FEB",1), MAR("MAR",2);
private DoubleEnumMonth(String a, int b) { }
}
public class Main {
public static void main(String[] args) {
System.out.println(DoubleEnumMonth.JAN);//JAN
}
}

可以看出,我们虽然只声明了双参数的构造子,并没有声明属性,也没有this赋值,但是依然可以通过toString()的方式直接访问到属性值.那肯定是编译器帮我们调用了super(a,b);来看一下

public final class DoubleEnumMonth extends Enum
{ public static final DoubleEnumMonth JAN;
public static final DoubleEnumMonth FEB;
public static final DoubleEnumMonth MAR;
private static final DoubleEnumMonth $VALUES[]; public static DoubleEnumMonth[] values()
{
return (DoubleEnumMonth[])$VALUES.clone();
} public static DoubleEnumMonth valueOf(String name)
{
return (DoubleEnumMonth)Enum.valueOf(demo7/DoubleEnumMonth, name);
} private DoubleEnumMonth(String s, int i, String a, int b)
{
super(s, i);
} static
{
JAN = new DoubleEnumMonth("JAN", 0, "JAN", 0);
FEB = new DoubleEnumMonth("FEB", 1, "FEB", 1);
MAR = new DoubleEnumMonth("MAR", 2, "MAR", 2);
$VALUES = (new DoubleEnumMonth[] {
JAN, FEB, MAR
});
}
}

这个结果,既有些意外之中,又意料之外.编译器,帮我们做了一个4个参数的构造函数.不用说前两个肯定还是name和index.至于后两个才是我们自己赋的值.

最后总结下.java的enum类型,自1.5出现后,就是为了简化我们创建一个集合类的不可改变类的.

enum一个最不像class的class的更多相关文章

  1. C语言中的共用体(union)和枚举(enum)

    1 union union Data{ int i; char ch; float f; }a={1, 'a', 1.5}; //错误 union Data a = {16}; //正确 union ...

  2. Js注释

    注释 介绍 作用 合作分享:方便他人阅读,便于分享 沉淀总结:容易忘记代码,自己总结沉淀 形式 1.// 双斜杠 2./**/斜杠星号 常用标签 标签 描述 @module 标明当前文件模块,在这个文 ...

  3. mysql数据类型整理

    mysql 中数据类型主要有三种 文本.数字 ,日期/时间 文本类型:char 定长,varchar变长,都是最多65535,char多了会截取,varchar少了自动补长.text最多65535,b ...

  4. AS 注解处理器 APT Processor MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. 《Java编程思想》笔记 第十九章 枚举类型

    1.基本enum特征 所有创建的枚举类都继承自抽象类 java.lang.Enum; 一个枚举类,所有实例都要在第一句写出以 ,隔开. 如果只有实例最后可以不加 : 枚举类因为继承了Enum,所以再不 ...

  6. 201871010112-梁丽珍《面向对象程序设计(java)》第六、七周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>    https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址> ...

  7. SQLite与MySQL区别

    原文链接:https://blog.csdn.net/zbw1185/article/details/47975965简单来说,SQLITE功能简约,小型化,追求最大磁盘效率:MYSQL功能全面,综合 ...

  8. SQLite和MySQL数据库的差别与应用

    简单来说,SQLITE功能简约.小型化,追求最大磁盘效率:MYSQL功能全面,综合化.追求最大并发效率.假设仅仅是单机上用的,数据量不是非常大.须要方便移植或者须要频繁读/写磁盘文件的话.就用SQLi ...

  9. SQLite、MySQL和PostgreSQL 三种关系数据库哪个好?

    关系型数据库的使用已经有相当长的时间了.它们变得流行起来托了管理系统的福,关系模型被实现得相当的好,并且被证明是操作数据的好方法(特别是事务性强的应用). 在这篇DigitalOcean文章中,我们将 ...

随机推荐

  1. 咕咕咕-HLPP算法

    hlpp(欢乐婆婆)算法总结 突然发现咕了好久(X) emm先大概说一下,hlpp是针对网络流算法的一种复杂度更优的算法,基于预流推进(即模拟) 复杂度上界为 n2根号m 且跑不满 (所以学会了它,可 ...

  2. [转]awsome c++

    原文链接 Awesome C++ A curated list of awesome C++ (or C) frameworks, libraries, resources, and shiny th ...

  3. 一句DELETE引发的加班(Mysql 恢复Delete删除的数据)

    本机用的Navicat连mysql测试DB又连了正式DB,因为本地与正式要频繁操作所以都打开了很多查询,本来要DELETE删除测试DB的数据,没看清在正式环境执行了.共删除了325条数据,然后在网上找 ...

  4. 深入理解JVM虚拟机(一):JVM运行时数据区

    概述: JVM将内存的管理进行封装,使得开发人员不必关心内存申请.释放操作.但是在高级程序开发.复杂业务场景开发的时候,如果出现内存溢出的情况,对于开发人员而言就很难去分析出原因.所以还是很有必要去了 ...

  5. cross validation交叉验证

    交叉验证是一种检测model是否overfit的方法.最常用的cross validation是k-fold cross validation. 具体的方法是: 1.将数据平均分成k份,0,1,2,, ...

  6. SMTP 与 IMAP

    (SMTP)邮件传输协议 :电子邮件写好后,由网络传输时的建立在tcp协议基础之上的协议 (IMAP)邮件访问协议:邮件到达目的服务器后,用户从用户的pc ,移动端,等到 接收邮件服务器上去访问自己的 ...

  7. E05 【餐厅】What kind of coffee or tea would you like?

    核心句型 What  kind  of  coffee or tea would you like? 你想喝什么咖啡或者茶? What  would  you like? 你喜欢什么?/你想要什么? ...

  8. MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化,数据库三大设计范式

    视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view tea ...

  9. C++随机马赛克图程序

    效果: 或者灰度,cell大小可调 代码: #include <opencv2\opencv.hpp> #include <Windows.h> struct paramete ...

  10. Netty线程模型(五)

    Netty支持单线程.主线程模型.主从多线程模型. 我们在创建线程组的时候,如果不传递参数,则默认构建的线程组线程是CPU核心数量. 一.单线程模型 在ServerBootstrap调用方法group ...