我有这样的方法:
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可以做到,但我必须这样做。
编辑:
我遇到的主要问题是,我可以获得堆栈输出,并查看调用我的方法2的方法——这是我需要的一个片段!此外,我还需要该方法的返回类型,但堆栈中没有该信息。现在,我可以从"调用method2的方法"所在的类中获取所有方法。这些方法的列表,包含所有内容,返回类型,输入参数。。但这是一个相当大的列表,有63种方法。所以我必须以某种方式对它们进行比较,以找出哪一个是STACK的那个。我不能用name来编译它们,因为有些会随着返回类型的不同而不同,hashcode也不同——这就是我的问题所在。
更新
如果您真的需要从堆栈跟踪中执行此操作(我强烈建议您避免),我认为您不能。堆栈跟踪可以告诉你类和方法的名称,但它不包括方法的参数类型,因此如果方法重载,你就无法判断哪一个调用了method2
。
我建议你重新审视你的设计。如果method2
需要知道调用它的方法的返回类型,那么有问题的方法应该将该信息传递给method2
。试图从运行时堆栈收集这些信息不仅效率低下,而且是设计上的一个危险信号。
示例:
public File method1(File f) {
// ...
method2(File.class);
}
public String method1(String s) {
// ...
method2(String.class);
}
public Foo method1(Foo f) {
// ...
method2(Foo.class);
}
method1
有三个过载。这对method2
来说不是问题,因为它们中的每一个都会告诉method2
其返回类型是什么—或者更准确地说,我希望,它需要method2
为它创建什么或其他什么。
原始答案
对于你列出的具体案例(尤其是在问题末尾),你可以这样做:
public File method1(){
method2(File.class);
}
File.class
是File
类的Class
实例。
对于在类中查找方法的返回值类型的一般情况,可以使用反射API。通过Class.forName
获取包含该方法的类的Class
实例,使用Class#getMethod
查找该Class
实例上的方法,然后在该Method
上使用Method#getReturnType
查找返回类型的类。
为什么反射如此困难?
public File method1() {
method2()
}
public void method2() {
Class<?> returnType = this.getClass().getMethod("method1").getReturnType();
}
当然,您必须处理异常。
如果您返回的类有一个空构造函数,您可以在method2()中本地构建一个返回类型的实例并使用它,但这是危险的,而且不是通用的。
您可以执行x.getClass().getName()并执行切换操作。
不过,我建议您考虑重新安排使用AspectJ,并在父调用中设置一个切入点,以便在堆栈中的信息太低之前收集您真正想要的信息。我对您的意图有点猜测,但任何时候您在解析堆栈输出以获取类型信息时,我都认为该设计值得重新审视。
更新答案
使用StackTrace和反射的组合
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Vector;
public class CallingMethodReturnType
{
public static void main( String[] args )
{
CallingMethodReturnType app = new CallingMethodReturnType();
app.method1();
app.method3();
}
public File method1(){
method2();
return null;
}
public ArrayList method3(){
method4();
return null;
}
public Vector method4() {
method2();
return null;
}
public void method2(){
Method method;
try {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement ste = stackTraceElements[2];
String callerMethodName = ste.getMethodName();
method = this.getClass().getMethod(callerMethodName, null);
Class returnType = method.getReturnType();
System.out.println(returnType);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
另请检查问题如何使用stacktrace或反射找到方法的调用方?如果你关心表现。
原始答案
你可以使用像这样的反射API
public method2(){
//do something and get method1 return type(in this case File)
Method method = this.getClass().getMethod("method1", null);
Class returnType = method.getReturnType();
}