本文参考

今天在Java Language Specification上偶然看到一条关于枚举的语法特点说明

An enum declaration is implicitly final unless it contains at least one enum constant that has a class body

不是很理解此处Class Body的所指,查阅了一些关于Java enum的语法介绍和stack overflow上的回答,对这句话有了一定的理解

https://stackoverflow.com/questions/9891613/why-cant-a-java-enum-be-final

不含Class Body的enum声明

public enum Color1 {

  RED("红色"),

  GREEN("绿色"),

  BLUE("蓝色");

  private String description;

  Color(String description) {

    this.description = description;
  }

  public String getDescription() {

    return description;
  }
}

不含Class Body的反编译结果

public final class Color1 extends Enum<Color1> {
    public static final /* enum */ Color1 RED = new Color1("RED", 0, "\u7ea2\u8272");
    public static final /* enum */ Color1 GREEN = new Color1("GREEN", 1, "\u7eff\u8272");
    public static final /* enum */ Color1 BLUE = new Color1("BLUE", 2, "\u84dd\u8272");
    private String description;
    private static final /* synthetic */ Color1[] $VALUES;

    public static Color1[] values() {
        return (Color1[])$VALUES.clone();
    }

    public static Color1 valueOf(String name) {
        return Enum.valueOf(Color1.class, name);
    }

    private Color1(String string, int n, String description) {
        super(string, n);
        this.description = description;
    }

    public String getDescription() {
        return this.description;
    }

    static {
        $VALUES = new Color1[]{RED, GREEN, BLUE};
    }
}

含Class Body的enum声明

这个例子中无法体现"至少有一个实例包含Class Body"的语法特点,但是后期验证确实如此,有兴趣可以改下代码自行尝试

public enum Color2 {

  RED {

    @Override

    public String getDescription() {

      return "红色";
    }
  },

  GREEN {

    @Override

    public String getDescription() {

      return "绿色";
    }
  },

  BLUE {

    @Override

    public String getDescription() {

      return "蓝色";
    }
  };

  public abstract String getDescription();
}

含Class Body的反编译结果

public abstract class Color2 extends Enum<Color2> {
    public static final /* enum */ Color2 RED = new /* Unavailable Anonymous Inner Class!! */;
    public static final /* enum */ Color2 GREEN = new /* Unavailable Anonymous Inner Class!! */;
    public static final /* enum */ Color2 BLUE = new /* Unavailable Anonymous Inner Class!! */;
    private static final /* synthetic */ Color2[] $VALUES;

    public static Color2[] values() {
        return (Color2[])$VALUES.clone();
    }

    public static Color2 valueOf(String name) {
        return Enum.valueOf(Color2.class, name);
    }

    private Color2(String string, int n) {
        super(string, n);
    }

    public abstract String getDescription();

    /* synthetic */ Color2(String x0, int x1, 1 x2) {
        this(x0, x1);
    }

    static {
        $VALUES = new Color2[]{RED, GREEN, BLUE};
    }
}

结论

enum实际上是一种特殊的class声明,enum实例(如上面代码示例中的RED、GREEN和BLUE)都被隐式地声明为public static final

当enum实例包含Class Body时,这种写法实际上生成了一个继承enum的特殊的内部类,所以enum声明不能够是final(声明为final的类无法被继承)

另外一个注意点,编译器不一定为enum声明隐式地添加public修饰符,若enum声明被包含在某个接口或类内,Java接口在编译时会自动为enum类型加上public static修饰符,而Java类在编译时会自动为 enum 类型加上static修饰符,具体可以参考这篇文章:

https://www.cnblogs.com/jingmoxukong/p/6098351.html

若没有任何实例包含Class Body 则enum被隐式声明为final的更多相关文章

  1. 构造函数、原型对象prototype、实例、隐式原型__proto__的理解

    (欢迎一起探讨,如果有什么地方写的不准确或是不正确也欢迎大家指出来~) PS: 内容中的__proto__可能会被markdown语法导致显示为proto. 建议将构造函数中的方法都定义到构造函数的原 ...

  2. JSP--JSP语法--指令--include(动态包含/静态包含)--九大隐式对象--四大域对象--JSP内置标签--JavaBean的动作元素--MVC三层架构

    一.JSP 原理:JSP其实就是一个servlet. Servlet负责业务逻辑处理,JSP只负责显示.开发中,JSP中不能有一行JAVA代码 二.JSP语法 1.    JSP模板元素:JSP中HT ...

  3. PHP 字符串的隐式转换规则以及针对包含字母的字符串的递增/递减操作

    之前一直对 PHP 中关于字符串的算数运算隐式类型转换规则和递增/递减操作符针对字符串的操作比较模糊,今天总结一下. 一.隐式转换 二进制算术运算符的隐式类型转换规则(http://php.net/m ...

  4. 从头认识java-13.9 隐式和显示的创建类型实例

    对于上一章节擦除引起的问题与解决的方法有读者提出过于简单.这里解释一下:由于笔者本身也遇不到对应的问题.仅仅是凭空想像一些有可能的问题,基于水平有限,因此上一章节写的比較简单,欢迎广大读者踊跃提意见, ...

  5. C#托管堆对象实例包含什么

    每个托管堆上的对象实例除了包含本身的值外,还包括:○ Type Object Ponter: 指向Type对象实例.如果是同类型的对象实例,就指向同一个Type对象实例.○ Sync Block In ...

  6. JavaScript调用后台的三种方法实例(包含两种Ajax)

    方法一:直接使用<%=%>调用(ASPX页面) 前台JS,代码如下: <script type="text/javascript"> var methodS ...

  7. ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等

    本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化.先上最终效果: →创建一个MVC4项目 ...

  8. 数据库查询实例(包含所有where条件例子)

    查询指定列 [例1] 查询全体学生的学号与姓名. SELECT Sno,Sname FROM Student: [例2] 查询全体学生的姓名.学号.所在系. SELECT Sname,Sno,Sdep ...

  9. KindEditor 4.1.11最新版 网站实例 包含使用方法 下载地址

    KindEditor是非常好的富媒体文本编辑系统,短小精悍,可惜网上找到的都是有各种问题!一怒之下,我自己进行了修改和配置,搞成了一个网站示例.下载解压后,可以直接运行!!完全无问题.! Kinded ...

随机推荐

  1. 小白学python第1问: int 占几个字节?

    windows 64位机器,python3.7:后面的文章中,没有特别说明的话,都是在该环境下运行 int 占几个字节? C语言中(GCC编译器),int 占据4个字节,python呢? 我们用pyt ...

  2. TCP三次握手中SYN,ACK,seq ack的含义

    转至:https://www.cnblogs.com/muyi23333/articles/13841268.html 1.TCP 为什么三次握手而不是两次握手 1.防止已失效的连接请求又传送到服务器 ...

  3. idea教程--如何申请免费的ideaIDE

    开始申请前请先到 https://www.jetbrains.com/zh/student/ 阅读免费学生授权的介绍和常见问题,再依照下方流程进行申请. (1)到 https://www.jetbra ...

  4. mapreduce类型对应

    public class OrderBean implements WritableComparable<OrderBean> { private Integer order_id; // ...

  5. Pycharm:运行程序时,不额外打开一个Console

    每次运行程序,比如A.py,都会额外生成一个Console,排列成一排的 A(2),A(3),... 那么如何关闭呢? 答案是:在Settings->Console中,勾选  'Use exis ...

  6. Python第一讲以及计算机基础

    本周课程安排 python基础(五天) 下周课程安排 tableau图形化表制作 下下周课程安排 spss 今日内容概要 计算机发展史 计算机主要硬件 编程与编程语言 python解释器及IDE编辑器 ...

  7. 使用 MobaXterm 连接矩池云 GPU服务器

    Host Name(主机名):hz.matpool.com 或 hz-t2.matpool.com,请以您 SSH 中给定的域名为准. Port(端口号):矩池云租用记录里 SSH 链接里冒号后的几位 ...

  8. VUE3 之 多个元素之间的过渡 - 这个系列的教程通俗易懂,适合新手

    1. 概述 老话说的好:过去不等于未来,过去成功了不代表将来也会成功,过去失败了也不代表将来也会失败. 言归正传,今天我们聊聊多个元素之间的过渡. 2. 多个元素之间的过渡 2.1 两个元素交替显示 ...

  9. tp6微信公众号开发者模式token认证

      微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架 技术标签: 微信公众号开发         因为工作的需要,这一两年对微信公众号和小程序,项目制作的比较多.所以我才打算写一篇全面的 ...

  10. laravel7 ORM和laravel模型操作

    1.什么是ORM 对象关系映射(Object Relation Maping),这个关系就是关系数据库.因此,顾名思义,ORM的核心是我们通过操作对应来操作关系数据库. ORM的优点:  ORM提供了 ...