我有以下代码:
package teste;
public class Teste {
public static void main(String[] args) {
String arroz = "abc";
Integer banana = 123;
vaiBuscar();
}
private static void vaiBuscar() {
Object[] obj = theMagicMethod();
System.out.println(((String) obj[0]));
System.out.println(((Integer) obj[1]));
}
}
输出应为:
abc
123
现在有趣的部分是,我可以定义的唯一方法是TheMagicMethod()。因此,我需要获取调用我的上层方法中定义的所有变量值。如果有办法做到这一点,可能是通过反思。
总结一下:如果除了定义方法theMagicMethod()之外,您还不能编辑代码的任何部分,那么该方法应该如何实现,以便使该程序的输出与我上面写的一样?
谢谢!
编辑:这实际上并不需要解决反射问题。任何方式都适合,它只需要工作即可。
在这些方法中,变量名会丢失。
Java是基于堆栈的计算机,因此一种方法看起来像
public int add(int first, int second) {
int sum = first + second;
return sum;
}
将会丢失字节码中sum的命名,该命名大致为
pushInt firstParameter
pushInt secondParameter
addInt
returnInt
请注意,中间变量名称sum
在编译过程中已被完全销毁,因此无法从运行时检索它。
但是,还有许多其他项必须按名称引用,因此它们的名称不会在运行时被破坏。其中一些包括
names of classes
names of members
names of methods
names of enums
names of interfaces
因此,可以在文件中获取所有已使用名称的子集.java
;但是,这样的子集将不会包含任何代码块的内部名称。
现在,如果您使用一些调试选项集(例如-g
)进行编译,则可以改善可访问名称的数量;但是,不能保证您读入的任何类都是在设置了调试标志的情况下编译的(实际上,大多数类都不在设置了调试标志的情况下进行编译以提高加载性能)。
如果您无法针对任何类执行此操作,则无法针对JVM执行此操作。
现在,如果您想尝试获取所有未在JVM中销毁的信息,则可以使用JDWP(调试线路协议),并了解一下暴露的内容。但是,我会怀疑它能否达到“一切”,因为它只能读取“由类加载器加载的一切”,并且(记住上面的声明)只能读取当时在编译中幸存的内容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句