Java反射:如何获取变量的名称?

新手上路,请多包涵

使用 Java 反射,是否可以获取局部变量的名称?例如,如果我有这个:

 Foo b = new Foo();
Foo a = new Foo();
Foo r = new Foo();

是否可以实现一种可以找到这些变量名称的方法,如下所示:

 public void baz(Foo... foos)
{
    for (Foo foo: foos) {
        // Print the name of each foo - b, a, and r
        System.out.println(***);
    }
}

编辑:这个问题不同于 Is there a way in Java to find the name of the variable that was passed to a function? 因为它更纯粹地询问是否可以使用反射来确定局部变量的名称,而另一个问题(包括接受的答案)更侧重于测试变量的值。

原文由 David Koelle 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

从 Java 8 开始,一些局部变量名信息可通过反射获得。请参阅下面的 “更新” 部分。

完整的信息通常存储在类文件中。一种编译时优化是删除它,节省空间(并提供一些混淆)。但是,当它存在时,每个方法都有一个局部变量表属性,其中列出了局部变量的类型和名称,以及它们在范围内的指令范围。

也许像 ASM 这样的字节码工程库可以让您在运行时检查这些信息。我能想到的唯一需要此信息的合理位置是在开发工具中,因此字节码工程也可能对其他用途有用。


更新: Java 8 添加 了对此的有限支持。参数(一种特殊的局部变量类)名称现在可以通过反射获得。除其他目的外,这有助于替换依赖注入容器使用的 @ParameterName 注释。

原文由 erickson 发布,翻译遵循 CC BY-SA 3.0 许可协议

根本 不可能。变量名称不会在 Java 中传递(并且可能由于编译器优化而被删除)。

编辑(与评论相关):

如果您放弃必须将它用作函数参数的想法,这里有一个替代方案(我不会使用 - 见下文):

 public void printFieldNames(Object obj, Foo... foos) {
    List<Foo> fooList = Arrays.asList(foos);
    for(Field field : obj.getClass().getFields()) {
         if(fooList.contains(field.get()) {
              System.out.println(field.getName());
         }
    }
}

如果 a == b, a == r, or b == r 或存在具有相同引用的其他字段,将会出现问题。

现在不需要编辑,因为问题得到澄清

原文由 Marcel Jackwerth 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题