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

时间:2015-04-29 10:15:44

标签: 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;
  }
}

此处所有枚举类型都没有constant Specific method,因此javac仅为enum创建一个类文件

OperationsType.class

但如果我在所有枚举类型的相同代码中添加constant Specific method,则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);
}

所以我怀疑为什么compiler为每个enum type创建了4个不同的类,如果他们有constant Specific method但是如果他们没有constant Specific method则不创建不同的类}?

2 个答案:

答案 0 :(得分:4)

使用匿名内部类实现具有常量特定方法的枚举。如The Java Language Specification中所述:

  

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

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

答案 1 :(得分: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的正文中,编译器并不知道参数的确切类型operation(是ADD还是SUB?),它只知道它是Operations类型的实例。为了正确调度apply的调用,VM需要知道参数的运行时类型。但是,如果您只有一个类,那么所有值都是不可能的。因此,编译器为每个值创建不同的类,并根据运行时类型调度调用。

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