我有一个枚举
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
则不创建不同的类}?
答案 0 :(得分:4)
使用匿名内部类实现具有常量特定方法的枚举。如The Java Language Specification中所述:
枚举常量的可选类主体隐式定义了一个 匿名类声明(§15.9.5),立即扩展 封闭枚举类型。阶级机构由通常的规则管理 匿名课程;特别是它不能包含任何构造函数。
匿名内部类是通过创建名称为OuterClass$1
,OuterClass$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需要知道参数的运行时类型。但是,如果您只有一个类,那么所有值都是不可能的。因此,编译器为每个值创建不同的类,并根据运行时类型调度调用。
另一方面,如果没有定义任何常量特定方法,则不需要创建子类,因为根据接收器对象的运行时类型,不需要调度任何操作。因此编译器只是省略了这些类的生成。