是否有办法获取在另一个类中调用的类的实例? 例如,如果 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
的非静态内部类),你运气不好。反射无法找到具有 Clazz
的 Foo
(从而获取 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'.
关于java - 使用反射获取 "owning"类中字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22847001/