简体   繁体   English

获取实例的声明类:可能吗?

[英]Getting the declaring class of an instance: possible?

Is there any way to retrieve the declaring class of an instance at runtime?有没有办法在运行时检索实例的声明类? For example:例如:

public class Caller {
    private JFrame frame = new JFrame("Test");
    private JButton button = new JButton("Test me");
    private Callee callee = new Callee();

    public Caller() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(button);

        button.addActionListener(callee.getListener());

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Caller();
    }
}

The callee:被叫方:

public class Callee {
    public ActionListener getListener() {
        return new ActionListener() {
        @Override
            public void actionPerformed(ActionEvent e) {
                /* Get the class "Caller" here and invoke its methods */
                /* Something along the lines of: */
                Object button = e.getSource();
                button.getOwnerClass(); //This would return the type Caller
            }
        };
    }
}

"getOwnerClass()" is an imaginary method. “getOwnerClass()”是一个虚构的方法。 Is there a way to get a result similar to that?有没有办法得到类似的结果?

There is nothing in the standard API that allows you to get this information.标准 API 中没有任何内容允许您获取此信息。 It's a bit unclear what you mean with 'declaring class' or 'owner class' but for this sake of this answer I'll assume that it is the class whose code created the instance of the object (that you want the owner class from).有点不清楚“声明类”或“所有者类”是什么意思,但为了这个答案,我假设它是其代码创建对象实例的类(您希望所有者类来自) .

This information is not stored by the JVM by default.默认情况下,JVM 不存储此信息。

But, using the heap profiler that is packaged along with the JDK distribution , you can record the stacktrace of the point at which objects are allocated, and this information can be written to a file on various points in time.但是,使用与 JDK 发行版一起打包的堆分析器,您可以记录对象分配点的堆栈跟踪,并且可以将这些信息在各个时间点写入文件。

That still doesn't give you an API call to retrieve the information, but it shows that it is technically possible to record this type of information.这仍然不会为您提供 API 调用来检索信息,但它表明在技术上可以记录此类信息。

I search a bit on Google and found that someone did create an API that uses the same basic technique as the heap profiler (the java.lang.instrumentation package/JVMTI interface)我在谷歌上搜索了一下,发现有人创建了一个 API,它使用与堆分析器相同的基本技术( java.lang.instrumentation包/JVMTI 接口)

With a bit of work you should be able to build something with it.通过一些工作,您应该能够用它构建一些东西。

The site has a nice example:该网站有一个很好的例子:

AllocationRecorder.addSampler(new Sampler() {
    public void sampleAllocation(int count, String desc, Object newObj, long size) {
      System.out.println("I just allocated the object " + newObj + 
        " of type " + desc + " whose size is " + size);
      if (count != -1) { System.out.println("It's an array of size " + count); }
    }
});

Instead of printing, you should get the stacktrace using new Exception().getStackTrace() , remove the first few StackTraceElement objects that refer to the sampler and the API classes, and then call StackTraceElement.getClassName() to get the name of the class that created the object instance, in other words, your OwnerClass.您应该使用new Exception().getStackTrace()获取堆栈跟踪,而不是打印,删除引用采样器和 API 类的前几个StackTraceElement对象,然后调用StackTraceElement.getClassName()以获取类的名称创建了对象实例,换句话说,就是您的 OwnerClass。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM