将字节码类型转换为java类型

时间:2017-08-28 08:08:40

标签: java bytecode

我想使用api将字节码类型转换为java而不是手动编码,是否有任何API?由于要求很高,我必须手动添加转换类型,这有点单调乏味。

[Ljava/lang/StackTraceElement;
J[Ljava/lang/StackTraceElement;
Ljava/util/Map;
Ljava/util/LinkedList;
Ljava/lang/String;
Ljava/net/URL;
Z
Ljava/lang/String;
[Ljava/net/URL;

以前我手动使用代码,如下所示。

 private static Type getType(final char[] buf, final int off) {
    int len;
    switch (buf[off]) {
    case 'V':
        return VOID_TYPE;
    case 'Z':
        return BOOLEAN_TYPE;
    case 'C':
        return CHAR_TYPE;
    case 'B':
        return BYTE_TYPE;
    case 'S':
        return SHORT_TYPE;
    case 'I':
        return INT_TYPE;
    case 'F':
        return FLOAT_TYPE;
    case 'J':
        return LONG_TYPE;
    case 'D':
        return DOUBLE_TYPE;
 }
}

当我使用asm库时,

Type.getArgumentTypes(desc);

它向我显示如下错误。

  

线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:44       at org.objectweb.asm.Type.getArgumentTypes(Unknown Source)

2 个答案:

答案 0 :(得分:0)

我会添加一个方法getTypeLength:

private static int getTypeLength(final char[] buf, final int off) {
    switch (buf[off]) {
        case 'V':
        case 'Z':
        case 'C':
        case 'B':
        case 'S':
        case 'I':
        case 'F':
        case 'J':
        case 'D':
            return 1;
        case 'L':
        {
            int i = offs+1;
            while (buf[i] != ';') {
                ++i;
            }
            return i-offs+1;
        }
        case '[':
            return getTypeLength(buf, off+1)+1;
    }
}

然后:

private static Type getType(final char[] buf, final int off) {
    int len;
    switch (buf[off]) {
        case 'V':
            return VOID_TYPE;
        case 'Z':
            return BOOLEAN_TYPE;
        case 'C':
            return CHAR_TYPE;
        case 'B':
            return BYTE_TYPE;
        case 'S':
            return SHORT_TYPE;
        case 'I':
            return INT_TYPE;
        case 'F':
            return FLOAT_TYPE;
        case 'J':
            return LONG_TYPE;
        case 'D':
            return DOUBLE_TYPE;
        case 'L':
        {
            int len = getTypeLength(buf, offs);
            String name = new String(buf, offs+1, len-2).replace('/', '.');
            return Class.forName(name);
        }
        case '[':
            int len = getTypeLength(buf, offs);
            return Class.forName(new String(buf, offs, len));
    }
}

答案 1 :(得分:0)

如果你正在使用asm,那就像这样,

Type.getType(desc).getClassName();

从asm库中键入类及其接受字符串的静态方法getType将字节码类型转换为java类型。