enum一个最不像class的class

2023-11-18

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());//31
    }
}

以上代码是创建了一个不可改变的月份表.内部实现就是一个在一个类中创建了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出现后,就是为了简化我们创建一个集合类的不可改变类的.

 

转载于:https://www.cnblogs.com/zumengjie/p/11592821.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • redis 主从哨兵模式搭建

    一 REDIS主从模式 搭建三个节点 同一个机器 三个端口 安装包 wget http download redis io releases redis 5 0 7 tar gz 安装步骤 https blog csdn net whg18
  • 【Linux】Linux和Window下\r与\n的区别、git命令行的使用

    作者 小卢 专栏 Linux Git 喜欢的话 世间因为少年的挺身而出 而更加瑰丽 人民日报 目录 1 回车换行符在Window下和在Linux下的区别 1 1回车换行符 1 2 行缓冲区打印 1 3进度条小程序 2 git命令行的使用 2
  • JAVA SM2 数字证书生成

    文章目录 Before Start Build with Maven QuickStart 生成自签名公私钥对 证书签名算法算法提供者 设置证书信息 标识信息构造 DN 获取扩展密钥用途构造 可选 证书信息构造 X 509格式证书对象生成
  • C语言版通讯录——动态存储(进阶版)

    前言 之前 我出了一期关于通讯录管理系统的项目实现 里面可以实现通讯录人员的增添改查显示以及排序统计功能 但那种只是以静态开辟内存的方式进行编写 大小固定死 若是达到上限便不可以再进行添加 这次优化 我会将静态存储改为动态存储 达到可以永久
  • idea双击启动无效,idea卡顿问题

    idea双击启动无效 大概率是关机时没有正确关闭idea 再次开机导致无法正常启动idea 1 通过任务管理器杀死idea进程后重启idea 2 需要修改配置 打开 以各自电脑实际为准 C Program Files JetBrains I
  • OpenResty简介、编译安装、新增 sticky模块(再编译)、升级

    OpenResty 也被称为 ngx openresty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 其内部集成了大量精良的 Lua 库 第三方的Nginx模块和大部分系统依赖包 用于方便地搭建能够处理超高并发 扩展性极高的
  • 找不到boost/noncopyable.hpp问题

    本人在vs2013使用boost库的时候 提示找不到boost noncopyable hpp文件 在百度和贴吧上找了很多资料 安装没出问题 只是在包含include的路径是为D boost 1 56 0 boost 本人将boost库直接
  • c++ 友元

    c 类中可以用friend关键字来声明友元 友元可以是另一个类或者类外的其他函数 友元只具有单向性例如 在类A中将类B声明为友元B可以查看A中的所有成员 而A不能查看B的私有成员 同理将一个函数声明为友元时这个函数也可以访问类中的所有成员
  • 6、微信小程序的布局

    文章目录 前言 一 传统基本布局 1 盒子模型 2 显示方式Display 3 定位position 4 溢出属性Overflow 5 浮动Float 6 对齐 二 Flex弹性布局 1 基本属性 2 使用示例 前言 wxss 指的是 We
  • (转)42个超实用的Google Chrome 插件,值得你拥有,建议收藏!

    每日英文 When friends ignore you don t be sad everyone has his own life who can not always be with you 当朋友忽略你时 不要伤心 每个人都有自己的
  • MySql语句查询某一级节点的所有子节点

    MySql语句查询某一级节点的所有子节点 在日常项目中 我们总能用到树型结构的数据 我们用代码去进行查询是比较麻烦的 这里提供一种sql语句查询父节点和子节点的方法 说明 只能当前节点查出所有子节点 不包含与当前节点平级的节点 且子节点是全
  • 事务,不只ACID

    1 什么是事务 应用在运行时可能会发生数据库 硬件的故障 应用与数据库的网络连接断开或多个客户端端并发修改数据导致预期之外的数据覆盖问题 为了提高应用的可靠性和数据的一致性 事务应运而生 从概念上讲 事务是应用程序将多个读写操作组合成一个逻
  • 微信h5分享好友和朋友圈功能

    在开发公众号H5项目时 如果想和小程序一样有分享朋友圈和好友功能时发现会不一样 开发微信小程序时做分享有会有onShareAppMessage 这个方法 因为H5有许多限制 所以在做微信H5分享时就比较麻烦了 首先明确一点 微信H5分享是没
  • Disruptor 详解

    Disruptor 详解 想了解一个项目 最好的办法就是 把它的源码搞到本地自己捣鼓 在网上看了 N 多人对 Disruptor 速度的吹捧 M 多人对它的机制分析 就连 Disruptor 官方文档中 也 NB 哄哄自诩 At LMAX
  • Netty学习17-Netty的可视化

    学习第41节 Netty 可视化方案 Console 日志定时输出 JMX 实时展示 ELKK TIG etc ChannelHandler Sharable public class MetricsHandler extends Chan
  • 08-----查找某个文件的路径

    1 使用find命令查找 关于find这个命令 非常强大 它可以根据文件大小 属性 用户 文件名等去查找匹配的文件 这里不再解释 这里只是列出常用的方法 查找某个文件并不输出错误 find name GetInfo 2 gt dev nul
  • 【Arthas】Arthas retransform动态重新加载类

    1 概述 转载 Arthas retransform动态重新加载类 2 开篇 Arthas提供retransform命令来重新加载已加载的类 通过该命令可以在有限制的反编译已加载的类重新修改后生成class文件重新加载 在测试环境中可以尝试
  • springboot参数配置

    全局配置文件 application properties 配置文件 先准备两个pojo实体类Pet和Person Component 用于将Person类作为Bean注入到spring容器中 ConfigurationProperties
  • 【js小游戏&案例】纯前端实现飞机大战,附带源码

    技能 使用html js css实现飞机大战小游戏 需求 我军飞机左右移动 并且按空格 可以发射炮弹 敌方飞机从上往下飞 接触到我方炮弹 飞机被歼灭 我军接触到敌军飞机也将会被歼灭 我方飞机吃到道具可以增加弹道 思路 初始化 初始创建我方飞
  • enum一个最不像class的class

    enum一个最不像class的classjava枚举类型是jdk5出现的 它的出现主要为了解决一些有特殊意义 已经确定的 长度不会改变的集合 月份描述 public class Month 月份名称 private final String