gpt4 book ai didi

java - 使用 Java Reflection 获取运行时上下文中所有定义的变量(内部有 voodoo)

转载 作者:行者123 更新时间:2023-12-01 22:48:35 27 4
gpt4 key购买 nike

我有这个代码:

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(调试线路协议(protocol))并查看公开的内容;但是,我怀疑它是否能够到达“所有内容”,因为它只能读取“类加载器加载的所有内容”并且(记住上面的语句)只能读取编译后幸存下来的内容。

关于java - 使用 Java Reflection 获取运行时上下文中所有定义的变量(内部有 voodoo),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25019301/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com