通过堆栈跟踪的Java反射

通过堆栈跟踪的Java反射,java,reflection,stack-trace,Java,Reflection,Stack Trace,在Java中,可以编写如下代码来查询堆栈: StackTraceElement[] stack = Thread.currentThread().getStackTrace(); for (StackTraceElement frame : stack) { System.out.println(frame.getClassName() + "." + frame.getMethodName()); } 是否有可能获得堆栈的反射视图,而不是只获取类和方法的名称,而是获取类和方法实例?如

在Java中,可以编写如下代码来查询堆栈:

StackTraceElement[] stack = Thread.currentThread().getStackTrace();
for (StackTraceElement frame : stack) {
    System.out.println(frame.getClassName() + "." + frame.getMethodName());
}

是否有可能获得堆栈的反射视图,而不是只获取类和方法的名称,而是获取类和方法实例?如果一个类中的两个方法共享一个名称(使用不同的参数),我可以在堆栈上区分它们吗?

类的
位很简单。使用:

StackTraceElement[]stack=Thread.currentThread().getStackTrace();
用于(StackTraceElement框架:堆栈){
字符串fqcn=frame.getClassName();
Class clazz=Class.forName(fqcn);
}
如果一个类中的两个方法共享一个名称(使用不同的参数),我可以在堆栈上区分它们吗


我不这么认为,因为
stackTraceeElement#getMethodName()
返回的方法名不包含参数编号和类型信息,这是您需要区分具有相同名称的方法的信息。

位很简单。使用:

StackTraceElement[]stack=Thread.currentThread().getStackTrace();
用于(StackTraceElement框架:堆栈){
字符串fqcn=frame.getClassName();
Class clazz=Class.forName(fqcn);
}
如果一个类中的两个方法共享一个名称(使用不同的参数),我可以在堆栈上区分它们吗

我不这么认为,因为
stackTraceeElement#getMethodName()
返回的方法名不包含参数编号和类型信息,这是区分同名方法所需的

是否有可能获得堆栈的反射视图,而不是只获取类和方法的名称,而是获取类和方法实例

通过调用类字符串上的
Class.forName
,可以获得
Class
实例;见马特·鲍尔的答案。(嵌套/内部/匿名类可能会有点棘手…)

如果一个类中的两个方法共享一个名称(使用不同的参数),我可以在堆栈上区分它们吗

只有当您拥有源代码时,应用程序才会使用调试信息进行编译,并且它能够对其进行解析,以确定哪些行号对应于哪些方法重载。最后一种方法需要大量的工作来实现,并且计算成本很高

(这种方法也有一个理论问题。可以在一行中使用多个方法重载编写Java源代码。如果这样做,就无法将方法与stacktrace中的信息区分开来。)

是否有可能获得堆栈的反射视图,而不是只获取类和方法的名称,而是获取类和方法实例

通过调用类字符串上的
Class.forName
,可以获得
Class
实例;见马特·鲍尔的答案。(嵌套/内部/匿名类可能会有点棘手…)

如果一个类中的两个方法共享一个名称(使用不同的参数),我可以在堆栈上区分它们吗

只有当您拥有源代码时,应用程序才会使用调试信息进行编译,并且它能够对其进行解析,以确定哪些行号对应于哪些方法重载。最后一种方法需要大量的工作来实现,并且计算成本很高


(这种方法也有一个理论上的问题。在一行中编写包含多个方法重载的Java源代码是可能的。如果这样做,就不可能将方法与stacktrace中的信息区分开来。)

对于第二个问题,我不这么认为。对于第二个问题,我不这么认为。还在看第二部分。MadProgrammer可能是对的。我想至少可以使用类似的技术来获得一组候选方法:调用getDeclaredMethods()并对名称进行筛选。是的,这是完全正确的。请记住不要在这里过于激动:堆栈跟踪用于调试目的。如果使用不同的类加载器加载(只要这两个类不是本机类),则可能有两个具有相同名称的不同类(包括包)。@Martin FCQNs每个类加载器必须是唯一的。不使用
#forName()
重载,该重载接受
类加载器
表示您正在使用当前的类加载器。仍在查看第二部分。MadProgrammer可能是对的。我想至少可以使用类似的技术来获得一组候选方法:调用getDeclaredMethods()并对名称进行筛选。是的,这是完全正确的。请记住不要在这里过于激动:堆栈跟踪用于调试目的。如果使用不同的类加载器加载(只要这两个类不是本机类),则可能有两个具有相同名称的不同类(包括包)。@Martin FCQNs每个类加载器必须是唯一的。不使用
#forName()
重载,该重载接受
类加载器
,表示您正在使用当前的类加载器。
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
for (StackTraceElement frame : stack) {
    String fqcn = frame.getClassName();
    Class<?> clazz = Class.forName(fqcn);
}