如何将编译的类名称与Java中的枚举成员匹配? [英] How to match compiled class name to an enum member in Java?

查看:122
本文介绍了如何将编译的类名称与Java中的枚举成员匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Java, with Sun's JDK 1.6, with an enum such as this:

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等中打印的方法调用将在top:

This also means that a stack trace showing foo(), or the method call printed in JVisualVM, etc., will have something like this at the top:

mypackage.MyEnum$1.run()

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

The $1 in the class name is due to the members of the enum being compiled to anonymous inner classes. I am wondering if it is safe to assume that the numbers used in these class names map to the order in which the enum members are defined? If it is not, is there a standard, guaranteed way to find the enum member from the number used as the anonymous class name?

EDIT

对于枚举的设计,这仅用于说明目的。真正的枚举实现了一个接口,每个成员提供了不同的方法实现。请不要过分注意什么显然看起来有点奇怪。

In regards to the design of the enum, this was used for illustration purposes only. The real enum implements an interface, and each member provides a different implementation of the methods. Please don't pay too much attention to what admittedly looks a bit strange.

编辑#2

试图以编程方式对此信息执行任何操作(例如奇怪的反射废话)。相反,我正在查找堆栈跟踪和分析信息,并试图映射枚举成员上的方法调用(显示为对匿名类的调用)对源代码中的实际枚举成员。

To clarify, I am not trying to do anything with this information programmatically (such as weird reflection nonsense). Rather, I am looking at stack traces and profiling information, and trying to map a method call on an enum member (shown as a call on an anonymous class) against the actual enum member in the source code.

推荐答案

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

In stacktraces, you'll also get the line number in the source file. Assuming you have the source, that'll reveal which constant it is. (In eclipse, simply click the line number in the console view to directly navigate to the source).

要查找类的常量名,可以抓取类文件,并反汇编静态初始化程序。例如,如果你编译:

To find the constant name for a class, you could grab the class file for the enum, and disassemble the static initializer. For instance, if you compile:

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;

但是可能有一个更优雅的方法,但如果一切都失败,

But there might be a more elegant method, but if all else fails, this should do the trick.

这篇关于如何将编译的类名称与Java中的枚举成员匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆