我的主要问题:我知道你可以通过反射来输出类字段,即使你不知道变量名,类型,甚至有多少。但是,有没有办法列出当前函数或当前范围内的所有变量,假设我不知道变量名是什么?
换句话说:
int x = 5;
int y = 42;
// some more code
//Now I want to println x and y, but assuming I cannot use "x" or "y".
我也对这个问题的答案感到满意: 假设我允许存储所有变量的名称,这有帮助吗? e.g:
Set<String> varNames = new HashSet<String>();
int x = 5;
varNames.add("x");
int y = 42;
varNames.add("y");
// some more code
//Now with varNames, can I output x and y without using "x" or "y"?
我为什么这么问?我正在使用ANTLR将XYZ语言翻译成java,我想提供一种简单的方法来在任何时间点输出程序的整个状态。
第三种可能的解决方案我很满意:如果在Java中这是不可能的,有没有办法可以为访问调用函数并检查堆栈的函数编写字节码?这也可以解决问题。
如果Java具有Python eval()
或php get_defined_vars()
的等价物,那将会令人惊讶。
如果它有所作为,我使用的是Java 6,但Java 5,6或7的任何内容都应该是好的。
谢谢!
答案 0 :(得分:4)
据我所知,你不能。至少,不是普通的Java代码。如果你能够在运行之前通过某种后处理器运行字节码,并假设你仍然使用包含的调试符号进行构建,那么你可以自动生成代码来实现它 - 但我不相信有通过反射访问当前堆栈帧中的局部变量的任何方式。
答案 1 :(得分:1)
如果您不想将此作为程序正常执行路径的一部分而仅用于调试,请使用Java platform debugger architecture (JPDA)。基本上,您可以编写自己的调试器,设置断点并使用JDI API来查询程序的状态。可以使用StackFrame#visibleVariables()列出局部变量。
如果以上不是一种选择,那将很难实现。要获取变量名称,可以解析类文件并读取方法的局部变量表属性。但是,获取局部变量值的唯一方法是通过aload / iload / etc。字节码指令。这些必须存在于您要分析的方法中,因此您无法将此功能放入其他辅助方法中。