ASM - 如何将Java字节码名称转换为Java类名?

6

我正在使用ASM(一种字节码修改库),它提供了访问字节码命名格式的类型名称,例如String字段的描述为:Ljava/lang/String。

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

有没有一种方法可以将内部名称转换为Java源代码格式?

3个回答

8
我不知道任何API方法,但是转换非常简单。你可以在JVM规范中找到详细信息。 原始类型由一个字符表示:
B = byte C = char D = double F = float I = int J = long S = short Z = boolean
类和接口类型由其完全限定名表示,具有'L'前缀和';'后缀。完全限定类名中的点号'.'将被替换为'/'(对于内部类,将用'$'代替外部类名称与内部类名称之间的'.')。因此,String类的内部名称将是"Ljava/lang/String;",内部类"java.awt.geom.Arc2D.Float"的内部名称将是"Ljava/awt/geom/Arc2D$Float;"。
数组名称以开放方括号'['开头,后跟组件类型名称(原始类型或引用类型)。因此,"int[]"变成了"[I",而"javax.swing.JFrame[][]"变成了"[ [Ljavax.swing.JFrame; "。

有个注意事项,就是不能使用内部类的完整限定名来动态实例化它。相反,你需要使用与Class.getName()返回值相同的名称,比如java.awt.geom.Arc2D$Float。 - Perception
谢谢,我本来希望有一些API可以用,但在这种情况下我会手动完成。 - mahonya

1

您可以使用{{link1:org.objectweb.asm.Type.getInternalName(java.lang.Class)}}。


3
这里有两个错误。1)原帖想要从内部形式转换为源代码形式,而这个方法则相反。2)原帖想要将一个字符串转换为Class.forName()可接受的参数,显然此时他并没有Class对象。 - Stephen C
6
正确的方式是 Type.getObject(className).getClassName() - FlightOfStairs
1
FlightOfStairs,为什么不将它添加为一个答案呢? - apetrelli

1

使用

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

示例:对于Ljava/lang/Deprecated;,返回java.lang.Deprecated。 通过@FlightOfStairs的提示找到了这个信息,他指出了正确的类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接