Why different class files are created for each enum type if they have constant-specific method?

无人久伴 提交于 2019-12-20 02:28:15

问题


i have one enum as

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

  private String opcodes;

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

  public String toString() {
    return this.opcodes;
  }
}

Here all enum type doesn't have any constant Specific method so javac is creating only one class file for enum as

OperationsType.class

but if i add constant Specific method in same code for all enum type then javac is creating 5 class files.

Operations.class
Operations$1.class
Operations$2.class
Operations$3.class
Operations$4.class

for below code

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

So i have doubt that why compiler has created 4 different classes for each enum type if they are having constant Specific method but not creating different classes if they don't have constant Specific method?


回答1:


Enums with constant-specific methods are implemented using anonymous inner classes. As mentioned in The Java Language Specification:

The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type. The class body is governed by the usual rules of anonymous classes; in particular it cannot contain any constructors.

Anonymous inner classes are implemented by creating class files with names like OuterClass$1, OuterClass$2 etc., and this is exactly what happens in the case of the enum.




回答2:


Consider the following class:

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

In the body of method testApply the compilier doesn't know the exact type of the argument operation (is it ADD or SUB?), it only knows that it is an instance of type Operations. In order to dispatch the invocation of apply correctly, the VM needs to know the runtime type of the argument. However if you only have one class for all values that would be impossible. Therefore the compiler creates different classes for each value and dispatches the invocation according to the run-time type.

On the other hand, if you do not define any constant specific methods then there is no need to create subclasses, since there are no operations that must be dispatched depending on the runtime type of the receiver object. Hence the compiler simply omits the generation of these classes.



来源:https://stackoverflow.com/questions/29940746/why-different-class-files-are-created-for-each-enum-type-if-they-have-constant-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!