为什么我可以匿名子类化枚举而不是最终类?

2023-11-27

这段代码:

public class Sandbox {
    public enum E {
        VALUE {
            @Override
            public String toString() {
                return "I'm the value";
            }
        };

        @Override
        public String toString() {
            return "I'm the enum";
        }
    }
    public static void main(String[] args) {
        System.out.println(E.VALUE);
    }
}

prints:

我就是价值

然而,这段代码:

public class Sandbox {
    public static final class C {
        @Override
        public String toString() {
            return "I'm a C";
        }
    }

    public static void main(String[] args) {
        System.out.println(new C() {
            @Override
            public String toString() {
                return "I'm anonymous";
            }
        });
    }
}

导致编译错误:

cannot inherit from final HelloWorld.C

Why can E.VALUE创建在我看来是匿名的东西E子类,覆盖toString方法,同时使用最终类而不是隐式最终枚举会引发编译时错误?

更具体地说,为什么可以VALUE覆盖任何内容E?我的印象是代码

public enum E {
    VALUE;
}

大致相当于

public static final class E {
    public static final E VALUE = new E();
}

在这种情况下,匿名性质将不被允许。

有什么不同?为什么枚举很特殊?


根据JLS:

枚举类型是隐式最终类型,除非它至少包含一个枚举 具有类体的常量。

在你的例子中,VALUE有一个类体,因此E不是隐式最终的。

Edit:下面是一个验证该声明的简单示例:

import java.lang.reflect.Modifier;

public class Sandbox {
  public enum E {
    VALUE {};
  }

  public enum E2 {
    VALUE;
  }

  public static void main(String[] args) {
    System.out.println(E.class);
    System.out.println(E.VALUE.getClass());
    System.out.println("E.VALUE is subclass of E = " + E.VALUE.getClass().getSuperclass().equals(E.class));
    System.out.println("E modifiers: " + Modifier.toString(E.class.getModifiers()));
    System.out.println("E2 modifiers: " + Modifier.toString(E2.class.getModifiers()));
  }
}

从输出中可以看到编译器正在添加final修饰符为E2但不E:

class Sandbox$E
class Sandbox$E$1
E.VALUE is subclass of E = true
E modifiers: public static
E2 modifiers: public static final

Edit #2:虽然E is not final并且是子类VALUE,明确尝试扩展它,例如class Foo extends E or enum Bar extends E是一个编译时错误8.1.4.超类和子类:

如果 ClassType 将类命名为 Enum 或 对它的任何调用。

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

为什么我可以匿名子类化枚举而不是最终类? 的相关文章

随机推荐

  • 在 C# 中将 4 字节数组转换为浮点数时出现问题

    我正在使用 C 并从某个控制器读取字节数组并将它们转换为其类型 除浮点值外 所有值 int string 都可以 假设得到的值为 533174 1 但是当读取数组时 byteArr 0 2 byteArr 1 73 byteArr 2 98
  • lambda 是否会在内存中保留任何数据?

    我在 AWS lambda 中有以下代码 const cache exports handler async event gt TODO implement if cache event key console log read from
  • 为什么这有效? (在C++中查找奇数)

    for unsigned int i 1 i lt 100 i if i 0x00000001 std cout lt lt i lt lt 为什么 以及如何 if i 0x00000001 找出奇数 0x00000001 is 1尽管它是
  • 无法加载 AppCompat ActionBar,出现未知错误?

    构建 gradle 文件 apply plugin com android application android compileSdkVersion 28 defaultConfig applicationId io dume dume
  • 在 PostgreSQL 中动态生成交叉表列

    我正在尝试创建crosstabPostgreSQL 中的查询 使其自动生成crosstab列而不是对其进行硬编码 我编写了一个函数 可以动态生成我需要的列列表crosstab询问 这个想法是将这个函数的结果替换为crosstab使用动态sq
  • 解析Java源代码

    我被要求开发一个软件 它应该能够创建输入Java源代码的流程图 控制流 于是我开始研究并得出以下解决方案 要创建流程图 控制流 我必须识别给定源代码中的控制语句和函数调用现在我有两种识别方法 通过编写我自己的语法来解析源代码 我认为这是一个
  • 如何从外部软件调用证明助手Coq

    如何从外部软件调用证明助手Coq Coq 有一些 API 吗 Coq 命令行界面是否足够丰富 可以在文件中传递参数并在文件中接收响应 我对 Java 或 C 桥感兴趣 这是合理的问题 Coq 并不是一种常见的商业软件 人们可以从中获得开发人
  • 如何将匿名类型作为参数传递?

    如何将匿名类型作为参数传递给其他函数 考虑这个例子 var query from employee in employees select new Name employee Name Id employee Id LogEmployees
  • 全局 var 与共享实例 swift

    Swift 中的全局变量和共享实例有什么区别 它们各自的使用领域是什么 任何人都可以根据 Swift 澄清他们的概念吗 全局变量是在文件顶层声明的变量 所以如果我们有一个名为Bar 您可以存储对实例的引用Bar在这样的全局变量中 var b
  • 为什么材质 FAB 在禁用时不改变颜色?

    我正在禁用材质浮动操作按钮 但当禁用设置为 true 时 颜色不会改变 我认为 Material 有一个 FAB 主题 禁用后它应该变成浅灰色 我不想在每次启用 禁用背景时添加代码来更改背景 我目前使用的材料版本 1 1 0 在代码中我只是
  • Java JMenuItem 动作监听器

    我的 JMenuBar 上的 ActionListener 需要一些帮助 没有错误 但是 每次我单击 JMenuItem 时 它都会触发与 JMenuItem 关联的所有操作 我的问题是 我在 ActionListener 代码中做得正确吗
  • Crashlytics:“我们缺少一个 dSYM 来处理崩溃”[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 Crashlytics 说 我们缺少 dSYM 来处理崩溃 当我尝试从 Xcode 7 1 下载 dSYM 时 我得到 没有可供下载的 dsym 我今天遇到了同样的问题 iTunes
  • 获取字典的随机样本[重复]

    这个问题在这里已经有答案了 我正在使用一本大字典 由于某种原因 我还需要处理该字典中的小随机样本 我怎样才能得到这个小样本 例如长度为2 这是一个玩具模型 dy a 1 b 2 c 3 d 4 e 5 我需要在 dy 上执行一些涉及所有条目
  • 通过 buildForm() 中的 $options 访问变量

    我想传递一个布尔值给我的DogForm dogForm new DogForm null array has cats gt this gt getUser gt hasCats form this gt createForm dogFor
  • mysql 按日期选择总和组

    快速提问 我有下表 total o date 35 01 11 2009 19 32 44 41 5 01 12 2009 22 33 49 61 5 01 23 2009 22 08 24 66 02 01 2009 22 33 57 2
  • 获取 HTML5 范围滑块手柄的偏移位置

    有什么办法可以得到pixelHTML5 范围输入的滑块手柄的位置
  • Python 3.7 安装无法在 openSUSE Leap 42.3 上运行

    在 openSUSE Leap 42 3 上从源代码构建和安装 Python 3 7 0 时 安装到 usr local 的默认 configure 会出现严重的 python 错误 openSUSE Leap 42 3 Python3 软
  • 如何在没有嵌入的情况下使用tensorflow seq2seq?

    我一直在研究使用张量流进行时间序列预测的 LSTM 现在 我想尝试序列到序列 seq2seq 在官方网站上有一个教程 展示了带有嵌入的 NMT 那么 如何在没有嵌入的情况下使用这个新的 seq2seq 模块呢 直接使用时间序列 序列 1 E
  • matplotlib轮廓可以匹配像素边缘吗?

    如何勾画像素边界matplotlib 例如 对于如下所示的半随机数据集 the code block that follows is irrelevant import numpy as np k for s in 2103 1936 22
  • 为什么我可以匿名子类化枚举而不是最终类?

    这段代码 public class Sandbox public enum E VALUE Override public String toString return I m the value Override public Strin