java - 使用反射获取 "owning"类中字段的值

标签 java reflection

是否有办法获取在另一个类中调用的类的实例? 例如,如果 Foo 类具有 Bar 类和 Clazz 类的实例, 有没有办法使用反射通过 Clazz 类获取 Bar 类的实例?

public class Foo{
  Bar b = new Bar();
  Clazz c = new Clazz();
}

public class Bar
{
   int i = 3;
}

public class Clazz
{
  //Code to get the instance of Bar running in Foo using Reflection
}

最佳答案

没有“Bar实例在Foo中运行”,因为您还没有实例化Foo。不,就目前情况而言,Clazz 不知道任何可能在字段中引用它的类,您必须添加这一点。

实现此目的的一种方法是通过正确使用 getter 并跟踪父对象:

public class Foo {
    Bar b = new Bar();
    Clazz c = new Clazz(this); // be warned: `this` is not fully constructed yet.
    public Bar getB () { return b; }
}

public class Clazz {
    private final Foo owner;
    public Clazz (Foo owner) {
        this.owner = owner;
    }
    public void example () {
        doSomething(owner.getB());
    }
}

或者,甚至更好,因为 Clazz 不再依赖于 Foo 并且您不必担心部分构造的 Foo,只需将 Bar 传递给 Clazz:

public class Foo {
    Bar b = new Bar();
    Clazz c = new Clazz(b); 
}

public class Clazz {
    private final Bar bar;
    public Clazz (Bar bar) {
        this.bar = bar;
    }
    public void example () {
        doSomething(bar);
    }
}

第二种方式也更自然地指示您的实际依赖项(Clazz 不关心它是否来自 Foo,它只关心有一个 酒吧)。

第一种方法的优点是允许 Foo 随时更改其 Bar (我注意到您没有在中声明 final b Foo) 并让 Clazz 了解更新后的值;当然,使用 Clazz#setBar(Bar b) 也可以完成同样的事情,而无需引入对 Foo 的错误依赖。

<小时/>

那里没有太多反射(reflection)的必要。但是,回应您下面的评论,您在其中写道:

The actual purpose of my question regards to a battleship tournament we are having in a CS class at my University. We are allowed to hack each other in order to find the ship deployment of our adversary.

不幸的是,假设您的代码片段是代码结构的准确表示,除非 Clazz 存储了创建它的 Foo 实例(或者是一个Foo 的非静态内部类),你运气不好。反射无法找到具有 ClazzFoo(从而获取 Bar),因为反射没有提供方法获取要搜索的所有实例化 Foo 的列表。如果您知道 Foo ,那么您可以获取其 b 成员,但您必须首先了解 Foo 实例。您也许可以在某处注入(inject)一些巧妙的字节代码来跟踪它,虽然有点先进,但请参阅 Java Bytecode Instrumentation ,或here for an overview

然后你写:

I have read that there is a way to find the instance of the Foo class through reflection if you know the name of the class.

不,不幸的是(如果我理解正确的话),there is no way to get an existing instance of a Foo given only its class name .

Is there anyway for me to find the Bar class if I find the Foo class?

如果您有一个 Foo 实例,并且您知道字段名称是 b,那么您可以执行以下操作:

Foo theFoo = ...; // your Foo instance

Field field = Foo.class.getDeclaredField("b");
Bar theBar = (Bar)field.get(theFoo); // get field "b" value from 'theFoo'.

参见Class.getDeclaredField()Field.get() .

关于java - 使用反射获取 "owning"类中字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22847001/

相关文章:

java - 如果 Android 可能有 JVM,那么字节码应该在 Android 上运行吗?

variables - dart - 镜像 - 如何使用镜像知道变量名称

vba - 有没有办法在 VBA 中获取枚举?

java - PDF 到达页面末尾时出现问题

java - 如何改变按键音量?

java - 如何在java中使用JFileChooser选择zip文件

java - 为什么我的构造函数中出现 StackOverflowError 异常

c# - 如何检查类型是否为类?

c# - 在不知道元素类型的情况下将项目添加到列表中

scala - 如何在Scala中测试类型较高的类型的一致性