public class Test
{
public String trytry()//把所有的方法都改成这种类型^_^,这样好玩么^_^呵呵
{
System.out.println("classjava");
return "trytry()";
}
public static void main(String[] args)
{
Test t=new Test();
System.out.println(t.trytry());
}
}
{
public String trytry()//把所有的方法都改成这种类型^_^,这样好玩么^_^呵呵
{
System.out.println("classjava");
return "trytry()";
}
public static void main(String[] args)
{
Test t=new Test();
System.out.println(t.trytry());
}
}
这样显然不行嘛
最简单例子,总众所周知的日志模块例如sun的日志模块.public static void Log.debug(Stirng debugMessage){
...
}其他任意一个函数调用:
package com.xx
public MClass{
public void otherFunction(....){
Log.debug("pring my message in this function");
}
}这样屏幕输出的并不是pring my message in this function
而是com.xx.MClass.otherFunction:pring my message in this function
当然我并不是要做一个日志模块(没那么无聊)我有另外的一个东西,类似于方法绑定,但是需要用到和日志模块一样的功能,就是获得掉用者的函数名.
我听说连sun的日志模块也是用抛异常的方法实现的,我没有研究过,但是真是没有别的办法,那我就失望了.......
交流ASP,PHP,JSP技术的,欢迎大家加入,一起交流
我觉得如果是要得到调用者的名字为什么不直接传一个参数给被调用方法?
被调用者
void fun(String useName) {
}
调用者
void useFun() {
fun(this.getClass()+".useFun");
}
你运行B的时候怎么知道是A调用了它?
不太可能实现吧
除非每次调用B之前都加入一下信息,这样挺麻烦的
public String fun(Object e)
{
return e.toString();}
try{
throw new Exection("get Invoker");
}catch(Exception e){
analizeExceptionStack(e);
}
}因为调用堆栈信息会保存在异常信息e里头,所以通过自己的analizeExceptionStack分析方法,是可以获得他的调用者函数名的.从另外一个角度说明,程序的函数调用过程是被保存在堆栈中的,而且现在至少是当异常抛出时会记录在Exception中.
换句话说,有没有别的途径,不通过Exception也可以获得他的调用堆栈信息呢???????
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;public class VectorProxy implements InvocationHandler {
private Object proxyobj; public VectorProxy(Object obj) {
proxyobj = obj;
} public static Object factory(Object obj) {
Class cls = obj.getClass(); return Proxy.newProxyInstance(
cls.getClassLoader(),
cls.getInterfaces(),
new VectorProxy(obj));
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method); Object o = method.invoke(proxyobj, args); return o;
} public static void main(String[] args) {
List v = null;
v = (List) factory(new Vector(10));
v.add("New");
v.add("York");
Iterator it = v.iterator();
}
}
示例代码如下(需要CGLIB包的支持,http://cglib.sourceforge.net/):import java.lang.reflect.Method;
import java.util.ArrayList;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;public class BeanProxy implements MethodInterceptor { public static Object newInstance(Class clazz) {
try {
BeanProxy interceptor = new BeanProxy();
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
e.setCallback(interceptor);
Object bean = e.create();
return bean;
} catch (Throwable e) {
e.printStackTrace();
throw new Error(e.getMessage());
}
} public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable { System.out.println(method); Object o = proxy.invokeSuper(obj, args); return o;
} public static void main(String args[]) {
ArrayList bean = (ArrayList) newInstance(ArrayList.class);
bean.add("New");
bean.add("York");
Iterator it = bean.iterator();
}
}
这个方法是可以窃取某一个类的所有方法调用,但是好像不是很符合我的要求啊.
1.这个方法只能知道这个类本身调用过什么方法,但他不能获取到,这个里面调用了些什么方法.也不能知道上层是谁调用了这个方法.换句话说,我写一个类B的方法F无论是让这个F充当Proxy本身,还是通过其他类充当Proxy,然后通知F,都不能让F知道倒地是谁调用了他.
2.如果要让其他类充当Proxy,那么太夸张了,那我岂不是要让我的所有的类都用个代理,然后调用的F的时候才能让F知道是谁调用它的????
这个不大现实啦~~~~~~
不过zcjl的方法好像前进了一步,我一定会给分的.另外还有一件事情,就是性能,我真的不希望这种Porxy方式会过大的影响性能,否则在做代理的时候我还是要慎重考虑一下,是否用回最土的代理模式
上面写的sample可以满足“如何在一个函数里面,在运行时获得调用这个函数的函数名????”如果楼主有什么具体的要求的话,不妨写出来
大家一起探讨一下至于楼主所说的:
“想知道某个方法调用了其他哪些方法,也想知道这个方法被其他哪些方法调用了”好像有个eclipse插件就实现了这样的功能
也许可以去研究一下它的实现方式
我写了一个函数,要根据调用者的函数名做一些处理.
比如我写的通用函数是C.F()
那么如果有另外一个函数调用这个函数,例如sample.testXXX()在这个testXXX()方法里面,显示的调用了我的函数C.F()那么我需要在C.F()中能知道,是谁调用它的:能获得调用它的那个函数的函数名,也就是"testXXX()"这个字符串,后续C.F()会根据这个字符串做一些特殊的操作.
这个要求有点想日志类Log.在日志类里面,它可以把调用它的函数信息甚至是掉的掉用,调用的掉用的调用的函数名,全部打印出来.
我稍微看了一下,异常机制最终也调用了一个native方法来实现对调用层次的跟踪