使用Java反射可以获取本地变量的信息吗?

22

我需要知道本地变量的类型。我正在使用Java反射,但是我无法获取它。请问你能告诉我如何知道本地变量的类型/名称吗?

我能否使用Java反射获取有关本地变量的信息?


非常相关,但是用于列出所有本地变量的代码如下:https://dev59.com/glXTa4cB1Zd3GeqP01s1 - Ciro Santilli OurBigBook.com
5个回答

21

假设你谈论的是方法或构造函数的局部变量,你无法使用反射来获取它们。你需要:

  • 使用字节码库,例如BCEL或ASM,或者
  • 使用远程调试器API之一。

后者将允许您访问局部变量的值,但仅在JVM被调试代理挂起时才能进行。

这两种方法都依赖于涉及的类编译时包含调试信息。具体来说,这些类需要使用“本地变量调试信息”编译;例如使用javac -g ...。默认情况下不包括“vars”调试信息。


10

简而言之,你不行。局部变量的名称不会被编译器保留。

作为一个快速实验,我使用Java 6和默认编译器选项编译了以下类:

public class X {
  public static void main(String[] args) {
    int var = 2;
    System.out.println(var);
  }
}

快速检查生成的.class文件可知,局部变量(var)的名称并没有出现在其中。


4
看我的回答。简单来说,如果你使用“-g”编译,信息应该会存在。 - Stephen C

6
不,使用Java反射是不可能的。像局部变量名之类的东西通常会被编译器删除以提供一些混淆和优化空间。有一个字节码库ASM可以在运行时检查事物的状态,这可能对您有用。

3

您可以使用字节码反向工程库(如ASM)来获取本地变量映射。但请注意,本地变量的名称可能不总是存在于字节码中,但其数量和类型始终存在。

无法通过反射获取此信息。反射仅适用于方法级别,而本地变量在代码块级别上。


1
  1. 对于“局部变量在代码块级别”的理解
- Gaurav

3
如果你所说的本地变量是实例变量和类变量,那么你可以按照以下方式进行:
String s = new String("This is a sample");
Class<String> type = s.getClass();
for ( Field f : type.getFields() ) {
    System.out.printf("Field %s is of type %s%n", f.getName(), f.getType().getName());
}

如果你所说的是“方法/构造函数中的局部变量”,那么你无法使用反射来访问它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接