6

I'm using ASM (a bytecode modification library) and it provides access to type names in the bytecode naming format, for example a String field is reported to have the description: Ljava/lang/String

I need to invoke Class.forName for some classes, but I need the source code form of the type names for that, e.g. java.lang.String.

Is there a way of converting from internal name to Java source format?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
mahonya
  • 9,247
  • 7
  • 39
  • 68

3 Answers3

8

I don't know any API method, but the conversion is quite simple. You cand find details in JVM spec here. Primitive types are represented by one character:

B = byte
C = char
D = double
F = float
I = int
J = long
S = short
Z = boolean

Class and interface types are represented by the fully qualified name, with an 'L' prefix and a ';' suffix. The dots '.' in the fully qualified class name are replaced by '/' (for inner classes, the '.' separating the outer class name from the inner class name is replaced by a '$'). So the internal name of the String class would be "Ljava/lang/String;" and the internal name of the inner class "java.awt.geom.Arc2D.Float" would be "Ljava/awt/geom/Arc2D$Float;".

Array names begin with an opening bracket '[' followed by the component type name (primitive or reference). An "int[]" thus becomes "[I" and a "javax.swing.JFrame[][]" becomes "[[Ljavax.swing.JFrame;".

Haozhun
  • 6,331
  • 3
  • 29
  • 50
zacheusz
  • 8,750
  • 3
  • 36
  • 60
  • With the caveat that you cannot actually instantiate an inner class dynamically using its FQN. You need to use the same name as would be returned by Class.getName() instead - in this case java.awt.geom.Arc2D$Float. – Perception Jul 22 '11 at 15:12
  • Thanks, I was hoping for some api, but I'll do it manually in this case. – mahonya Jul 24 '11 at 22:49
1

You can use org.objectweb.asm.Type.getInternalName(java.lang.Class).

Chandra Sekhar
  • 16,256
  • 10
  • 67
  • 90
Slonopotamus
  • 201
  • 1
  • 5
  • 3
    This is wrong in 2 ways. 1) The OP wants to convert from the internal form to the source code form. This method goes the other way. 2) The OP wants to convert a String so that he can pass it as an argument to `Class.forName()`. Obviously, he doesn't have the `Class` object at this point. – Stephen C May 15 '12 at 03:03
  • 6
    A correct way would be `Type.getObject(className).getClassName()`. – FlightOfStairs May 27 '12 at 16:20
  • 1
    FlightOfStairs, why don't you add it as an answer? – apetrelli Apr 26 '16 at 11:34
1

Use

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

Example: for Ljava/lang/Deprecated; returns java.lang.Deprecated. Found this thanks to hint from @FlightOfStairs who pointed at right class.

Avallach
  • 11
  • 1