是否可以更容易地检查方法是否超越了超类?

时间:2012-12-22 10:28:41

标签: java java-bytecode-asm

我正在尝试创建简单的Java混淆器,以便使用OW2的ASM在运行时修改字节码来创建它。

我的目标是重命名每个类,字段和方法名称,但如果MethodNode很容易存在于超类中,我无法弄清楚如何删除

我目前递归循环遍历当前类中的每个超类,并查看方法是否存在同名和签名

private boolean isSuperMethod(MethodNode method, ClassNode node) {
    if(node.superName == null)
        return false;
    boolean exists = false;
    ClassNode cn = null;
    try {
        ClassReader cr = new ClassReader(node.superName);
        cn = new ClassNode();
        cr.accept(cn, 0);
    } catch (IOException e) {
        e.printStackTrace();
    }
    for(MethodNode superMethod: (List<MethodNode>)cn.methods) {
        boolean sameSignature = (superMethod.signature == null && method.signature == null) || superMethod.signature.equals(method.signature);
        if(superMethod.name.equals(method.name) && sameSignature) {
            System.out.println(superMethod.name + " exists in parent class(" + cn.name + ")");
            exists = true;
            break;
        }
    }
    return exists || isSuperMethod(method, cn);
}

是否有更清洁或更快的方法来实现这一目标,因为这看起来有点矫枉过正?

1 个答案:

答案 0 :(得分:0)

当JVM加载一个类时,它会在所谓的方法表中组织这些类的方法。此方法表按名称和描述符标识每个方法。因此,您所做的是确定重写方法的唯一方法。 (检查Overridden注释不是解决方案,因为此注释未在编译类中保留,它仅用作Java编译器的指令。)

当您考虑在编译B extends A之后更改类A的类B时,这一点就变得更加明显了。如果B覆盖了A的方法,则在重新编译后不一定是这样。

但有一点,方法的签名与被覆盖的方法无关。您应该检查描述符