【问题标题】:Can I get the instance of the calling object in Java?我可以在 Java 中获取调用对象的实例吗?
【发布时间】:2017-08-21 16:52:52
【问题描述】:

有一个库用几个参数调用我的方法。我想接收另一个参数,但库没有将它提供给它调用的方法。

通过反编译库,我可以看到它有参数,并且它被分配给一个实例变量(不是私有的,但也不是公共的。)我知道如果我有实例,我可以使用反射来获取变量,但我也没有实例。

有什么方法可以访问实例吗? SecurityManager has getClassContext(),但这只是给了我实例的类 - 我想要实例本身。

作为我想要的一个简单示例:

public class A {
    int b;
    public A(int b, int c) {
        this.b = b;
        D(c);
    }
}

public class D {
    public D(int c) {
        // Somehow I want to get at the calling instance of A's b from here,
        // and A belongs to a library which I didn't write.
    }
}

或者...我知道b 被用作调用堆栈上的参数。因此,如果有人知道我如何访问传递给A 的构造函数的b,那将是可以接受的。

如果这些都不可行...我可以反编译 A 并按照我想要的方式编译它,然后我要么需要做一些类加载向导,要么我必须修改 jar 的内容.这些听起来都不理想,所以我希望有人知道如何从调用堆栈访问A 的实例或b 的参数。

【问题讨论】:

  • 如果“b”没有吸气剂,你就不应该得到它......或者那是一个可怕的图书馆。您可以尝试将对象序列化为可读字符串(例如使用 Gson 或其他库的 Json),但我不确定它是否会为您提供已编译库中对象的私有字段。
  • @Wietlol - 如果b 有一个吸气剂,那么这里没有区别。问题是我需要找出如何获取正在构造DA 的实例。
  • 啊,我明白了。简单来说,这是不可能的。但是,如果您可以跟踪创建了“A”的哪个对象,则可以将其放入静态变量中。但是,在这种情况下,这可能只能通过覆盖 A
  • 为什么还要得到A的实例呢?
  • @MCEmperor - 所以我可以从中得到b。好的,所以在实际场景中,我正在使用的库希望我为类​​提供加密和解密密码的方法。不过,它传入的只是加密或解密的字符串。我想通过包含随机生成的每用户盐来加强这一点。所以我需要获取用户名,但图书馆没有提供。我已经反编译了库并且知道它有用户名,但它没有将它传递给我的方法 - 它只提供一个字符串。

标签: java reflection stack-trace callstack


【解决方案1】:

借助您提供的代码,我可以考虑编写一个方面,我的意思是使用 aop 并尝试使用 joinpoint 来获取传递给构造函数 A() 的参数

【讨论】:

【解决方案2】:

不知何故,我想从这里获取 A 的 b 的调用实例

简短的回答:你不能。

长答案:如果您在调试器或您自己的自定义 JVM 上运行它,您可以获得它。

另一种解决方案:使用像 AspectJ 这样的框架的面向方面编程

【讨论】:

  • 我相信这将在 OpenJVM 上运行......这会改变什么吗?我认为我无法改变这一点。 JVM 确实有运行它的 byteman 的副本...我知道我以前使用过 byteman 来提取变量并将它们放入日志文件中...是否也可以使用它来访问调用实例?
  • 为什么要放入日志文件?我会直接在 IDE 中使用调试器,这样更方便。我添加了第三个选项,您可能会觉得有趣。
【解决方案3】:

你不能那样做。详情请见this post

没有“所有者”之类的东西,因此您无法获取调用实例,除非指定了对父级的显式引用:

class A {
    int b;
    A(int b, int c) {
        this.b = b;
        new D(this, c);
    }
}

class D {
    D(A a, int c) {
        ...
    }
}

似乎根据库您不应该获得这样的实例,或者它设计不佳。

【讨论】:

    猜你喜欢
    • 2014-10-09
    • 2021-12-29
    • 2022-06-26
    • 2021-01-04
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2020-01-25
    • 2014-03-08
    相关资源
    最近更新 更多