java:是否可以知道枚举项使用哪个构造函数进行初始化?

时间:2015-09-28 02:53:56

标签: java reflection constructor enums initialization

正如标题所说,我想知道是否有可能通过编程方式来了解枚举项目用于初始化的构造函数,我认为如果有这样的机制它应该可以通过使用反射访问但我有没有找到类似的东西,更具体:

我有什么

enum AnEnum {

    E1(1),
    E1(1, 2);

    int v;

    AnEnum(int p1) {
        v = p1;
    }

    AnEnum(int p1, int p2) {
        v = p1 + p2;
    }

} 

我需要的是是一种告诉我是否使用一个或两个参数构造函数初始化实例的机制,如果我能获得用于初始化它的参数,那就更好了。

2 个答案:

答案 0 :(得分:2)

asm这样的字节码工具可以让你看到如何构造某个枚举值。

尝试java -classpath“asm.jar; asm-util.jar; yourjar.jar”AnEnum并查看临床方法:

...
mv.visitMethodInsn(INVOKESPECIAL, "temp/AnEnum", "<init>", "(Ljava/lang/String;II)V", false);
mv.visitFieldInsn(PUTSTATIC, "temp/AnEnum", "E1", "Ltemp/AnEnum;");
...
mv.visitMethodInsn(INVOKESPECIAL, "temp/AnEnum", "<init>", "(Ljava/lang/String;III)V", false);
mv.visitFieldInsn(PUTSTATIC, "temp/AnEnum", "E2", "Ltemp/AnEnum;");

你可以看到使用signature(String,int,int)调用E1,使用signature(String,int,int,int)调用E2。前导(String,int)可能是字符串名称和Enum值的数值,因此您应该只对剩余的参数感兴趣。

答案 1 :(得分:0)

您将无法检测到调用了哪个构造函数,但构造函数可以只存储您可以访问的参数值。在这个例子中,我使用Integer的Object类型。如果使用了第二个构造函数并且没有p2,那么它的值将为null。

enum AnEnum {

    E1(1),
    E2(1, 2);

    int v;
    Integer p1;
    Integer p2;

    AnEnum(int p1) {
        this.v = p1;
        this.p1 = p1;
    }

    AnEnum(int p1, int p2) {
        this.v = p1 + p2;
        this.p1 = p1;
        this.p2 = p2;
    }

    public Integer getP1() {
        return this.p1;
    }

    public Integer getP2() {
        return this.p2;
    }
}