2014-04-03 78 views
1

有無論如何獲得在另一個類中調用的類的實例嗎? 例如,如果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 
} 

回答

0

沒有「的BarFoo運行實例」,因爲你還沒有實例化一個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,只要傳遞BarClazz

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的優勢(我注意到你沒有申報在Foofinal b),並有Clazz瞭解更新的價值;當然,同樣的事情可以用Clazz#setBar(Bar b)完成,而不會在Foo上引入錯誤的依賴關係。


沒有太大必要進行反思那裏。然而,應對下面的評論,你寫:

我的問題的實際目的問候,我們都在我的大學的CS類有戰艦的比賽。我們被允許互相攻擊,以便找到對手的艦船部署。

不幸的是,然後 - 假設您的代碼段是代碼結構的精確表示 - 除非Clazz存儲創建它(或是非靜態內部類Foo的)的Foo的一個實例,你運氣不好。找不到具有Clazz(因此獲得Bar)的Foo,因爲反射並不提供獲取所有實例化的Foo的列表以供搜索的手段。如果您知道Foo,那麼您可以獲得其b成員,但您必須知道Foo實例的開頭。您可能可以在某處注入一些巧妙的字節代碼來進行跟蹤,但有點高級,但請參閱Java Bytecode Instrumentationhere 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()

+0

我不喜歡你說的話,但我的例子只是我試圖實現的一個通用示例。我的問題的實際目的是關於我們在我大學的CS課堂中參加的戰艦比賽。我們被允許互相攻擊,以便找到對手的艦船部署。這就是爲什麼我想知道如何通過反思來獲得類或實例的名稱的原因。 –

+0

嗯,我知道Foo類的名字是什麼。我已經讀過,如果你知道類的名字,有一種方法可以通過反射來找到Foo類的實例。無論如何,如果我找到Foo課程,我還能找到Bar課程嗎? –

+0

@AlanW我已經更新了我的回答,並附有評論的答案以及示例代碼片段。 –

相關問題