获取在Java中调用特定方法的对象的hashCode()

时间:2015-05-25 08:15:12

标签: java java-bytecode-asm javassist bytecode-manipulation

我想要的是获得hashCode()'在Java中调用特定方法的对象的值。例如,

public class Caller {
    public void aMethod() {
        Callee calleeObj = new Callee();
        calleeObj.aSpecificMethod();
        //do something
    }
}

我想知道的是Caller的hashCode()值,它在运行时调用calleeObj.aSpecificMethod()。它用于绘制如下的Object图。

enter image description here

作为约束,我只能修改' .class'使用字节码检测技术的文件。

要做到这一点,我已经尝试Javassist库在Callee.aSpecificMethod()内进行检测,但这种方式无法获取调用方的对象。原因似乎很明显,因为在Callee.aSpecificMethod()' Callee'只能访问Caller上的代码,而不是-file (login, logout) master (register, view) 类。

有没有办法使用Javassist捕获调用者对象的hashCode()值?我也考虑过ASM 5.0,但是使用ASM 5.0是最后一个选择,因为到目前为止我已经构建了许多基于Javassist的代码。

2 个答案:

答案 0 :(得分:4)

正如其他人所说,调用方法没有办法接触调用者对象,但到目前为止,没有人指出你为什么永远不可能这样做的原因:

关于你的请求的一个很大的误解是你假设必须有一个“调用者对象”。但是没有这样的事情。您的方法可能会被static方法调用,例如直接来自应用程序的main方法,也来自类初始化器或构造函数,甚至在super构造函数调用期间,换句话说,在调用上下文中存在对象的位置但尚未完全构建,因此在hashCode()无法调用的地方。

如果您没有在想法中考虑这些差距,则不应该开始使用Instrumentation来更改调用者的字节代码。你不太可能生成正确的代码。即使在调用引用中存在实例的地方,该实例也不需要可用,也不需要哈希代码计算。如果从另一个对象的hashCode方法调用方法会怎样?

除了实际的障碍,最重要的问题是,为什么你认为你需要“调用者”哈希码?你打算用它做什么,它不可能是正确的。想一想以下代码:

public class Caller {
    public void aMethod() {
        Callee calleeObj = new Callee();
        new Thread(calleeObj::aSpecificMethod).start();
    }
}

您感兴趣的哈希码是什么?在运行时生成的匿名类的实例?调用该匿名类的Thread方法的run实例?或者调用方法时,Caller实例根本不在调用堆栈上?

答案 1 :(得分:0)

您必须将调用对象或其哈希代码作为参数传递给方法。