2015-05-25 16 views
3

具体的方法是什么,我想是让'的hashCode()调用Java中的特定方法的对象的值对象的hashCode()方法。例如,为了得到调用Java中

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

我想知道的是它在运行时调用calleeObj.aSpecificMethod()来电人的hashCode()值。它用于绘制如下的对象图。

enter image description here

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

为了做到这一点,我已经试过Javassist库仪器内部Callee.aSpecificMethod()但这种方式无法获得来电者的物体。究其原因似乎是显而易见的,因为在“Callee.aSpecificMethod()”改动的代码只能在Callee类,而不是Caller类接入代码。

有没有办法捕捉的hashCode()使用了Javassist调用者的物体的价值?我也在考虑ASM 5.0,但使用ASM 5.0是最后一种选择,因为我迄今为止基于Javassist构建了许多代码。

+3

改变方法? 'calleeObj.aSpecificMethod(this.hashCode())' – immibis

+0

你也可以为调用者对象更改类吗?如果是这样的话,只需按照@immibis的建议添加一个参数即可。否则,我不认为这是可能的。 (如果从静态上下文中调用'hashCode'会发生什么?即,没有调用对象。) – aioobe

+0

嗨,你可能会想尝试与AOP的东西(的AspectJ)来实现这一目标? –

回答

4

至于说其他人,也没有被调用的方法得到手主叫对象的方式,但到目前为止,没有人指着你的原因所在,这将永远不可能:

左右的大误解你的请求是你假设必须有一个“调用者对象”。但是没有这样的事情。您的方法可能会被static方法调用,例如,即使在构造函数调用期间,换句话说,在调用上下文中存在对象但尚未完全构造的地方,也可以从类初始化器或构造函数中调用该方法,因此在不能调用hashCode()的地方。

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

而且实际障碍,最大的问题是,为什么你认为你需要的“来电”的哈希码?你打算用它做什么,它不可能是正确的。想想下面的代码:

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

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

+0

Yeap。在尝试了一些技巧之后,我也同意你的意见。这从我的好奇心开始知道Java程序的运行时的结构和它紧密相连的软件体系结构理论。但无论如何,在这一点上,我完全同意你的看法。感谢您的解释。 – byron1st

0

你必须通过其中的调用对象或它的哈希代码作为参数传递给该方法。

+0

Yeap。我同意。似乎没有办法使用Javassist。我应该考虑其他方式,包括ASM。 – byron1st