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. C# in 参数修饰符

    in 修饰符记录: 新版C# 新增加的 in 修饰符:保证发送到方法当中的数据不被更改(值类型),当in 修饰符用于引用类型时,可以改变变量的内容,单不能更改变量本身. 个人理解:in 修饰符传递的数 ...

  2. RabbitMQ、RPC、SaltStack "贡"具的使用

    消息队列 使用队列的场景 在程序系统中,例如外卖系统,订单系统,库存系统,优先级较高 发红包,发邮件,发短信,app消息推送等任务优先级很低,很适合交给消息队列去处理,以便于程序系统更快的处理其他请求 ...

  3. js中this由来

    这篇文章主要是讲述js中的this是什么?是怎么来的? 我们首先创建一个person对象,如下: var person = { name: 'wyh', age: 22, sayHi: functio ...

  4. Android培训准备资料之UI一些相似控件和控件一些相似属性之间的区别

    这一篇博客主要收集五大布局中的一些相似控件和控件一些相似属性之间的区别 ImageView ImageButton Button 三者有啥区别? (1)Button继承自TextView,ImageV ...

  5. 汇编之JCC指令

    版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-06,21:59:16.作者By-----溺心与沉浮----博客园 JCC指令决定它跳不跳转跟别的没关系,只跟EFLAG标 ...

  6. elasticsearch 集群、节点、索引、分片、副本概念

    原文链接: https://www.jianshu.com/p/297e13045605 集群(cluster): 由一个或多个节点组成, 并通过集群名称与其他集群进行区分 节点(node): 单个 ...

  7. nginx反向代理和负载均衡的基本配置

    一.反向代理的基本配置 在原本默认的nginx上修改server配置 server { listen 2222;#监听请求端口 server_name 192.168.100.3;#监听请求地址,ng ...

  8. Linux中断管理 (3)workqueue工作队列【转】

    转自:https://www.cnblogs.com/arnoldlu/p/8659988.html 目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机 ...

  9. postgreSQL 自动递增序号

    创建表格 CREATE TABLE test ( id serial, name ) not null ); 查询当前创建好的表格 插入数据 BEGIN TRANSACTION; INSERT INT ...

  10. SpringBoot整合easyexcel实现Excel的导入与导出

    导出 在一般不管大的或者小的系统中,各家的产品都一样,闲的无聊的时候都喜欢让我们这些程序员导出一些数据出来供他观赏,非说这是必须需求,非做不可,那么我们就只能苦逼的哼哧哼哧的写bug喽. 之前使用PO ...