[英]Obtain value of a field in an “owning” class using 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
}
因為沒有實例化Foo
,所以沒有“ Bar
在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
,它只在乎擁有Bar
)。
第一種方法的優點是允許Foo
隨時更改其Bar
(我注意到您沒有在Foo
聲明final b
),並讓Clazz
知道更新的值。 當然,使用Clazz#setBar(Bar b)
可以完成相同的操作,而不會引入對Foo
的錯誤依賴。
那里沒有太多需要反思的地方。 但是,請在下面的評論中寫您的評論:
我的問題的實際目的與我們在我的大學的CS班中進行的戰艦錦標賽有關。 我們被允許互相攻克,以便找到我們對手的飛船部署。
不幸的是,那么-意味着你的片斷是代碼結構的精確表示-除非Clazz
存儲的實例Foo
創建它(或者是一個非靜態內部類的Foo
),你的運氣了。 用反射無法找到具有該Clazz
的Foo
(並因此獲得Bar
),因為反射不能提供一種獲取所有實例化Foo
列表進行搜索的方法。 如果您知道Foo
則可以獲取其b
成員,但是您必須先了解Foo
實例。 您也許可以在某個地方注入一些聰明的字節碼來跟蹤它,這有點先進,但是請參閱Java Bytecode Instrumentation或此處的概述 。
然后,您寫:
我讀過,如果您知道類的名稱,則可以通過反射找到Foo類的實例。
不,很不幸(如果我對您的理解正確), 僅給出類名 , 就無法獲得Foo
的現有實例 。
如果我找到Foo類,反正我還能找到Bar類嗎?
如果您有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'.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.