Java 如果每个枚举类型具有常量特定的方法,为什么要为它们创建不同的类文件?

Java 如果每个枚举类型具有常量特定的方法,为什么要为它们创建不同的类文件?,java,enums,.class-file,Java,Enums,.class File,我有一个枚举 enum OperationsType { ADD("+"), SUB("-"), DIV("/"), MUL("*"); private String opcodes; private OperationsType(String opcodes) { this.opcodes = opcodes; } public String toString() { return this.opcodes; } } 这里所有的枚举类型都没有任何

我有一个枚举

enum OperationsType {
  ADD("+"), SUB("-"), DIV("/"), MUL("*");

  private String opcodes;

  private OperationsType(String opcodes) {
    this.opcodes = opcodes;
  }

  public String toString() {
    return this.opcodes;
  }
}
这里所有的枚举类型都没有任何
常量特定方法
,因此
javac
只为
enum
创建一个类文件

OperationsType.class
但如果我在相同的代码中为所有枚举类型添加
常量特定方法
,那么
javac
将创建5个类文件

Operations.class
Operations$1.class
Operations$2.class
Operations$3.class
Operations$4.class
对于以下代码

enum Operations {
ADD("+") {
    public double apply(double a, double b) {
        return a + b;
    }
},
SUB("-") {
    public double apply(double a, double b) {
        return a - b;
    }
},
DIV("/") {
    public double apply(double a, double b) {
        return a / b;
    }
},
MUL("*") {
    public double apply(double a, double b) {
        return a * b;
    }
};

private String opcodes;

private Operations(String opcodes) {
    this.opcodes = opcodes;
}

public abstract double apply(double a, double b);
}

因此,我怀疑为什么
编译器
为每个
枚举类型
创建了4个不同的类,如果它们具有
常量特定方法
,但如果它们没有
常量特定方法
,则不创建不同的类?

使用匿名内部方法实现具有常量特定方法的枚举上课。如中所述:

枚举常量的可选类主体隐式定义 匿名类声明(),它立即扩展 封闭枚举类型。阶级团体是由通常的规则来管理的 匿名类;特别是它不能包含任何构造函数


匿名内部类是通过创建名为
OuterClass$1
OuterClass$2
等的类文件来实现的,这正是枚举的情况。

考虑以下类:

public class Test {
    public double testApply(Operations operation, double a, double b) {
        return operation.apply(a, b);
    }

    public static void main(String[] args) {
        Test test = new Test();
        assert 3.0 == test.testApply(OperationsType.ADD, 2.0, 1.0);
        assert 1.0 == test.testApply(OperationsType.SUB, 2.0, 1.0);
    }
}
在方法体
testApply
中,编译器不知道参数
操作的确切类型(是
ADD
还是
SUB
?),它只知道它是类型
操作的一个实例。为了正确地分派
apply
调用,VM需要知道参数的运行时类型。但是,如果所有值只有一个类,这是不可能的。因此,编译器为每个值创建不同的类,并根据运行时类型分派调用


另一方面,如果您没有定义任何特定于常量的方法,那么就不需要创建子类,因为根据接收方对象的运行时类型,没有必须调度的操作。因此,编译器只是省略了这些类的生成。

常量特定方法”是什么意思?@EJP对于每个枚举类型(即添加)
apply
方法被实现,这个方法是
常量特定方法
。您没有回答自己的问题吗?在第二种情况下,需要有几个类来重写apply()方法,而在第一种情况下,则不是。因为每个枚举实例都重写抽象apply()方法。如果没有子类,则无法重写方法。是。除非它不是代理。它是一个子类。