沒有「的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
,它只關心有一個Bar
)。
第一種方式是允許Foo
在任何時候改變其Bar
的優勢(我注意到你沒有申報在Foo
final b
),並有Clazz
瞭解更新的價值;當然,同樣的事情可以用Clazz#setBar(Bar b)
完成,而不會在Foo
上引入錯誤的依賴關係。
沒有太大必要進行反思那裏。然而,應對下面的評論,你寫:
我的問題的實際目的問候,我們都在我的大學的CS類有戰艦的比賽。我們被允許互相攻擊,以便找到對手的艦船部署。
不幸的是,然後 - 假設您的代碼段是代碼結構的精確表示 - 除非Clazz
存儲創建它(或是非靜態內部類Foo
的)的Foo
的一個實例,你運氣不好。找不到具有Clazz
(因此獲得Bar
)的Foo
,因爲反射並不提供獲取所有實例化的Foo
的列表以供搜索的手段。如果您知道Foo
,那麼您可以獲得其b
成員,但您必須知道Foo
實例的開頭。您可能可以在某處注入一些巧妙的字節代碼來進行跟蹤,但有點高級,但請參閱Java Bytecode Instrumentation或here for an overview。
,然後寫:
我已閱讀,有找到通過反射的Foo類的實例,如果你知道類的名稱的方式。
不,不幸的是(如果我理解你的話),there is no way to get an existing instance of a Foo
given only its class name。
如果找到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'.
見Class.getDeclaredField()
和Field.get()
。
我不喜歡你說的話,但我的例子只是我試圖實現的一個通用示例。我的問題的實際目的是關於我們在我大學的CS課堂中參加的戰艦比賽。我們被允許互相攻擊,以便找到對手的艦船部署。這就是爲什麼我想知道如何通過反思來獲得類或實例的名稱的原因。 –
嗯,我知道Foo類的名字是什麼。我已經讀過,如果你知道類的名字,有一種方法可以通過反射來找到Foo類的實例。無論如何,如果我找到Foo課程,我還能找到Bar課程嗎? –
@AlanW我已經更新了我的回答,並附有評論的答案以及示例代碼片段。 –