在java中是否可以在运行时获取对象的声明名?

在java中是否可以在运行时获取对象的声明名?,java,reflection,Java,Reflection,假设代码中有一个按钮:“jbuttonclosebutton”。我不知道它叫“关闭按钮”,但这正是我想知道的 在运行时,该按钮被点击,一旦点击,我就可以通过反射和AWTAPI找到很多关于它的信息——但我不能做的是找到它在哪里——它在代码中是如何调用的,它声明为什么名称(“closeButton”) 有可能从JVM中找到这一点吗 有没有一种方法可以编译和运行代码,从而在运行时保留实例的名称 在这种情况下,是否有某种类型的“javaagent”(如果可能,免费)可以帮助我 谢谢 编辑(美国东部夏令时

假设代码中有一个按钮:“jbuttonclosebutton”。我不知道它叫“关闭按钮”,但这正是我想知道的

在运行时,该按钮被点击,一旦点击,我就可以通过反射和AWTAPI找到很多关于它的信息——但我不能做的是找到它在哪里——它在代码中是如何调用的,它声明为什么名称(“closeButton”)

有可能从JVM中找到这一点吗

有没有一种方法可以编译和运行代码,从而在运行时保留实例的名称

在这种情况下,是否有某种类型的“javaagent”(如果可能,免费)可以帮助我

谢谢

编辑(美国东部夏令时14:23):


我以按钮为例,但它可以是任何类型的组件,可以保存一个值,并附加ActionListeners。我可以通过反射获得关于该组件的所有信息,但我在代码中找不到它。即使有10个组件声明了相同的名称,这仍然给了我一个线索,我可以消除可能性。

我认为您有两种方法:

  • 使用java调试API,即将程序转换为小型调试器
  • 使用字节码工程库

  • 简短回答:这是不可能的

    详细信息:您所称的
    name
    实际上与
    JButton
    的实例无关。只有变量保存了允许在运行时访问该实例的引用。此示例代码将显示此mor:

    JButton newButton = new JButton();
    JButton otherButton = newButton;
    
    这里两个变量都引用同一个JButton实例。

    
    
    
    import java.lang.reflect.*;

    public class field1 { private double d; public static final int i = 37; String s = "testing";

      public static void main(String args[])
      {
         try {
            Class cls = Class.forName("field1");
    
            Field fieldlist[] 
              = cls.getDeclaredFields();
            for (int i 
              = 0; i < fieldlist.length; i++) {
               Field fld = fieldlist[i];
               System.out.println("name
                  = " + fld.getName());
               System.out.println("decl class = " +
                           fld.getDeclaringClass());
               System.out.println("type
                  = " + fld.getType());
               int mod = fld.getModifiers();
               System.out.println("modifiers = " +
                          Modifier.toString(mod));
               System.out.println("-----");
            }
          }
          catch (Throwable e) {
             System.err.println(e);
          }
       }
    
    导入java.lang.reflect.*

    公共类字段1{ 私人双d; 公共静态最终int i=37; 字符串s=“测试”

    publicstaticvoidmain(字符串参数[])
    {
    试一试{
    Class cls=Class.forName(“字段1”);
    字段列表[]
    =cls.getDeclaredFields();
    用于(int i)
    =0;i
    }

    这将为您提供一个类中所有字段的列表。

    如果您的“变量”是一个字段,那么使用反射的解决方案(在另一个答案中提到)是有效的

    如果变量是局部变量,理论上可以使用JVMTI代理获取其名称,前提是使用调试信息编译类。检查时,您的局部变量是否在范围内。没有人改变它的值,也没有其他具有相同值的变量(在这种情况下,您无法决定需要哪个变量)


    但是,你绝对不应该做任何一件事。这些都是理论上的可能性,类似于狠狠地揍自己以至于昏倒。

    如果不运行java debugger,这是不可能的-为什么要这样做?我正在处理的应用程序非常庞大(数百万行),组件会被创建并传递到各个类中。它们的标签是动态创建的。在这种情况下,它实际上是我需要做的事情的一个领域,我只是用一个按钮作为例子。我最深切的哀悼给你。抱歉,格式化被搞乱了,我现在没有太多的时间来修复它。非常好-我喜欢反射。只要在空白行上加上4个空格,这将修复它。“米迦勒-我也一样。”我每天都在滥用它们,虽然这实际上是我第一次用Java来实现真正的目的,而不仅仅是为了看看我是否能做到。这是一次很好的尝试,但它不起作用,我今天早上已经尝试过了。“getdeclaringClass()”返回null.typo:
    newButton()-->
    新按钮
    是否有一种方法可以在运行时将引用映射到名称?所有AWT组件都有一个
    名称
    属性,这可能就是您要查找的。