【问题标题】:ASM - How can I convert Java class name from Java bytecode name?ASM - 如何从 Java 字节码名称转换 Java 类名称?
【发布时间】:2011-07-22 12:50:44
【问题描述】:

我正在使用 ASM(一个字节码修改库),它提供对字节码命名格式的类型名称的访问,例如,一个字符串字段被报告为具有描述:Ljava/lang/String

我需要为某些类调用 Class.forName,但我需要类型名称的源代码形式,例如java.lang.String.

有没有办法将内部名称转换为 Java 源格式?

【问题讨论】:

    标签: java reflection bytecode java-bytecode-asm


    【解决方案1】:

    我不知道任何API方法,但是转换很简单。您可以在JVM spec here 中找到详细信息。 原始类型由一个字符表示:

    B = 字节
    C = 字符
    D = 双
    F = 浮动
    我 = 整数
    J = 长
    S = 短
    Z = 布尔值

    类和接口类型由完全限定名表示,带有 'L' 前缀和一个 ';'后缀。点“。”在完全限定的类名中是 替换为“/”(对于内部类,分隔外部类名和内部类名的“.”被替换为“$”)。所以 String 类的内部名称是“Ljava/lang/String;”内部类“java.awt.geom.Arc2D.Float”的内部名称将是“Ljava/awt/geom/Arc2D$Float;”。

    数组名称以左括号“[”开头,后跟组件类型名称(原始或引用)。因此,“int[]”变为“[I”,“javax.swing.JFrame[][]”变为“[[Ljavax.swing.JFrame;”。

    【讨论】:

    • 需要注意的是,您实际上不能使用 FQN 动态实例化内部类。您需要使用与 Class.getName() 返回的名称相同的名称 - 在本例中为 java.awt.geom.Arc2D$Float。
    • 谢谢,我希望有一些 api,但在这种情况下我会手动完成。
    【解决方案2】:

    【讨论】:

    • 这在两个方面是错误的。 1)OP想要从内部形式转换为源代码形式。这种方法反其道而行之。 2) OP 想要转换一个字符串,以便他可以将其作为参数传递给Class.forName()。显然,此时他没有Class 对象。
    • 正确的方法是Type.getObject(className).getClassName()。
    • FlightOfStairs,你为什么不添加它作为答案?
    【解决方案3】:

    使用

    org.objectweb.asm.Type.getType(typeDescriptor).getClassName()
    

    例如:Ljava/lang/Deprecated; 返回java.lang.Deprecated。 感谢@FlightOfStairs 的提示,他指出了正确的班级。

    【讨论】:

      猜你喜欢
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 2021-05-22
      • 1970-01-01
      相关资源
      最近更新 更多