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

标签 java enums anonymous-types final

这段代码:

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);
    }
}

打印:

I'm the value

但是,这段代码:

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

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

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

public enum E {
    VALUE;
}

大致相当于

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

在这种情况下,匿名性质是不允许的。

有什么区别?为什么枚举很特别?

最佳答案

根据JLS :

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

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

编辑:这是一个验证声明的简单示例:

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

编辑#2: 尽管 E 不是 final 并且是 VALUE 的子类,但明确尝试扩展它,例如使用 class Foo extends Eenum Bar extends E 根据 8.1.4. Superclasses and Subclasses 是编译时错误:

It is a compile-time error if the ClassType names the class Enum or any invocation of it.

关于java - 为什么我可以匿名子类化枚举而不是最终类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16970615/

相关文章:

c# - 为什么在枚举声明中使用 int?

python - 在python中创建一个匿名类实例

c# - 如何使用表达式树构建匿名对象

java.lang.OutOfMemory错误: GC overhead limit exceeded android studio

java - 如何将数据库中的所有可用表设置为文本字段

java - Jackson 反序列化子类型将枚举字段设置为 null

c# - 具有多个值的枚举名称

c# - 如何传递匿名类型作为参数?

java - java 中的编码组合

java - 如何查看mysql连接的默认端口号?连接不工作! jdbc连接