我有这样的方法:
public File method1(){
method2()
}
public method2(){
do something..
and get method1 return type(in this case File)
}
我如何得到它?我尝试这样..
Throwable t = new Throwable();
StackTraceElement[] elements = t.getStackTrace();
并获取元素的所有方法。之后,getReturnType
,但它不起作用。我也尝试过
public File method1(){
method2(this.getClass());
}
public method2(Class<?> className){
//problem here
}
,但这里的问题是我无法比较两个元素,即堆栈上的元素和来自 classname.getMethods()
的元素。
有什么方法可以将方法返回类型发送到 method2
吗?我需要这个是因为要制作一些类似历史的日志。我知道可以用aspectJ 来完成,但我必须像这样做。
编辑:
我遇到的主要问题是我可以获得堆栈输出,并查看调用我的 method2 的方法 - 这是我需要的一个片段!我还需要该方法的返回类型,但堆栈不保存该信息。现在,我可以从“调用method2的方法”所在的类中获取所有方法。这些方法的列表包含所有内容、返回类型、输入参数……但这是一个相当大的列表,有 63 个方法。所以我必须以某种方式比较它们,找出哪一个是来自堆栈的。我无法使用名称来比较它们,因为有些返回类型不同,哈希码不同 - 这就是我陷入困境的地方。
I have methods like this:
public File method1(){
method2()
}
public method2(){
do something..
and get method1 return type(in this case File)
}
How do I get it? i tried like this..
Throwable t = new Throwable();
StackTraceElement[] elements = t.getStackTrace();
and get all the methods for the elements. And after that, getReturnType
, but it doesn't work. I also tried
public File method1(){
method2(this.getClass());
}
public method2(Class<?> className){
//problem here
}
But here the problem is that i can't compare two elements, the one on the stack and the one from classname.getMethods()
.
Is there any way that I can send method return type to a method2
? I need this because of making some history-like log. I know it can be done with aspectJ but I have to do it somehow like this.
EDIT:
The main problem I have is that I can get stack output, and see the method who called my method2 - that's one fragment I need! Also I need that method's return type, but the stack doesnt hold that information. Now, I can get all the methods from the class where the "method who called method2" is. The list of those methods, hold everything, return type, input parameters.. but that's a pretty big list, 63 methods. So I have to compare them somehow to find out which one is the one FROM STACK. I can't comapre them using name, because some differ with return type, hashcode is different - that's where I'm stuck.
发布评论
评论(4)
更新
如果您确实需要从堆栈跟踪中执行此操作(我强烈建议避免这样做),我认为您不能。堆栈跟踪可以告诉您类和方法名称,但它不包括方法的参数类型,因此如果方法重载,您将无法判断哪个方法称为
method2
。我建议您重新审视您的设计。如果
method2
需要知道调用它的方法的返回类型,那么相关方法应该将该信息传递给method2
。尝试从运行时堆栈收集该信息不仅效率低下,而且是一个设计危险信号。示例:
我们有
method1
的三个重载。这对于method2
来说不是问题,因为它们都告诉method2
它的返回类型是什么——或者更准确地说,我希望,什么它需要method2
来为其创建或其他什么。原始答案
对于您列出的具体情况(尤其是问题末尾),您可以执行以下操作:
File.class
是Class
File
类的实例。对于查找类中方法的返回值类型的一般情况,您可以使用 反射 API。通过
Class.forName
,使用 Class 实例上的方法href="http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29" rel ="nofollow">Class#getMethod
,然后使用Method#getReturnType< /code>
在该
Method
上查找返回类型的类。Update
If you really need to do this from a stack trace (which I would strongly recommend avoiding), I don't think you can. The stack trace can tell you the class and method names, but it doesn't include the method's argument types, and so if the method is overloaded you can't tell which one called
method2
.I recommend you revisit your design. If
method2
needs to know the return type of the method that calls it, then the method in question should pass that information intomethod2
. Attempting to gather that information from a runtime stack is not only inefficient, but it's a design red flag.Example:
There we have three overloads of
method1
. This is not a problem formethod2
, because each of them tellsmethod2
what its return type is — or more accurately, I hope, what it needsmethod2
to create for it or whatever.Original answer
For the specific case you list (esp. toward the end of your question), you can do this:
File.class
is theClass
instance for theFile
class.For the general case of finding the type of the return value of a method in a class, you can use the reflection API. Get the
Class
instance for the class containing the method viaClass.forName
, look up the method on thatClass
instance usingClass#getMethod
, then useMethod#getReturnType
on thatMethod
to find out the return type's class.为什么反思这么难?
当然,您必须处理异常情况。
Why is it so difficult with reflection?
Of course, you'll have to handle the exceptions though.
如果您返回的类有一个空构造函数,您可以在 method2() 中本地构建返回类型的实例并使用它,但这很危险并且不通用。
您可以执行 x.getClass().getName() 并执行切换操作。
不过,我建议您考虑重新构建它以使用 AspectJ 并在其中放置一个切入点在你的堆栈太低之前,你的父母会打电话来收集你真正想要的信息。我对您的意图进行了一些猜测,但是每当您解析堆栈输出以获取类型信息时,我认为该设计都值得再看一下。
If the class you are returning has an empty constructor, you could build a instance of the return type locally in method2() and use that, but that is dangerous and not generic.
You could do x.getClass().getName() and perform a switch operation.
What I would suggest, though, is that you consider rearchitecting this to use AspectJ and put a cut point in your parent call to collect the information you really want before you get too low in the stack. I'm guessing a little bit as to your intent, but any time you are parsing the stack output for type information I think the design deserves a second look.
更新答案
结合使用 StackTrace 和 Reflection
另请检查问题 如果您关心性能,如何找到使用堆栈跟踪或反射的方法的调用者?。
原始答案
您可以像这样使用反射API
Updated answer
Using combination of StackTrace and Reflection
Also check question How do I find the caller of a method using stacktrace or reflection? if you are concerned with performance.
Original answer
You can use reflection API like this