gpt4 book ai didi

java - 如何将编译后的类名与 Java 中的枚举成员匹配?

转载 作者:搜寻专家 更新时间:2023-11-01 02:33:24 25 4
gpt4 key购买 nike

在 Java 中,使用 Sun 的 JDK 1.6,使用如下枚举:

public enum MyEnum {
FIRST_MEMBER { public void foo() { } },
SECOND_MEMBER { public void foo() { } },
THIRD_MEMBER { public void foo() { } };
}

编译后的文件是:

MyEnum$1.class  MyEnum$2.class  MyEnum$3.class  MyEnum.class 

这也意味着显示 foo() 的堆栈跟踪,或在 JVisualVM 中打印的方法调用等,将在顶部有类似这样的内容:

mypackage.MyEnum$1.run()

类名中的$1是由于枚举的成员被编译为匿名内部类。我想知道假设这些类名中使用的数字映射到枚举成员定义的顺序是否安全?如果不是,是否有一种标准的、有保证的方法从用作匿名类名的数字中找到枚举成员?


编辑

关于枚举的设计,这仅用于说明目的。真正的枚举实现了一个接口(interface),每个成员提供了不同的方法实现。请不要太在意那些确实看起来有点奇怪的东西。


编辑#2

澄清一下,我并没有试图以编程方式对这些信息做任何事情(比如奇怪的反射废话)。相反,我正在查看堆栈跟踪和分析信息,并尝试将对枚举成员的方法调用(显示为对匿名类的调用)映射到源代码中的实际枚举成员。

最佳答案

在堆栈跟踪中,您还将获得源文件中的行号。假设你有来源,那将揭示它是哪个常数。 (在 Eclipse 中,只需单击控制台 View 中的行号即可直接导航到源代码)。

要找到一个类的常量名称,您可以获取枚举的类文件,然后反汇编静态初始值设定项。例如,如果您编译:

enum PieceColor {
Black {
@Override public String toString() { return "dark";}
},
White {
@Override public String toString() { return "light";}
}
}

然后做:

javap -c PieceColor

你得到:

static {};
Code:
0: new #13; //class tools/PieceColor$1
3: dup
4: ldc #15; //String Black
6: iconst_0
7: invokespecial #16; //Method tools/PieceColor$1."<init>":(Ljava/lang/String;I)V
10: putstatic #20; //Field Black:Ltools/PieceColor;
13: new #22; //class tools/PieceColor$2
16: dup
17: ldc #24; //String White
19: iconst_1
20: invokespecial #25; //Method tools/PieceColor$2."<init>":(Ljava/lang/String;I)V
23: putstatic #26; //Field White:Ltools/PieceColor;

但可能有更优雅的方法,但如果所有其他方法都失败了,这应该可以解决问题。

关于java - 如何将编译后的类名与 Java 中的枚举成员匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3998861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com