通过堆栈跟踪的Java反射
在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()); } 是否有可能获得堆栈的反射视图,而不是只获取类和方法的名称,而是获取类和方法实例?如
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);
}