2010-10-22 59 views
1

我想知道是否有可能,使用反射或類似的東西來調用一個方法,每當一個變量在讀取或寫入模式下訪問。簡而言之,我的目標與C#屬性的行爲類似。Java +反射:調用變量訪問方法。可能嗎?

例子:比方說,我有兩個類A和B ...

public class A{ 
    public int field; 

    public void foo(){ System.out.println("Field modified");} 
} 

public class B{ 
    public void bar(A a){ 
     a.field = 1; 
    } 
} 

...我想執行每當a.field寫入方法A.foo()。

這是可以在Java中實現嗎?

在此先感謝

p.s.我知道好的編程習慣建議使用getter和setter。我只需要知道我想做什麼是可行的。

交流

+1

C#屬性是getter和setter的語法糖。 – 2010-10-22 16:09:47

+0

我知道它們是句法糖,但考慮一下你需要測試/調試別人編寫的代碼的場景,並且想要跟蹤變量的訪問方式。在C#中,您可以解決將類的變量轉換爲屬性的問題,並保持代碼的其餘部分不變。編譯器會處理所有內容 – Jack 2010-10-22 16:29:46

+0

如果您正在測試某人的代碼,您可以獲取源代碼的副本並對其進行修改。或者首先反編譯代碼。 – 2010-10-22 17:35:58

回答

7

不通過反射 - 反射只是讓你訪問有關的類/場/等靜態信息在運行時。

Aspect oriented programming更符合您的想法 - 這可以讓您在源代碼的某些位置(例如在方法運行之前,設置字段時等)插入小部分代碼(稱爲「建議」) )。這幾乎肯定會讓你做你正在尋找的東西。

一個警告,但 - 你似乎回暖,這是不太可能是一個好主意,依靠您的一般邏輯方面也很難和他們講道理,制定出會發生什麼時(根據定義,它們打破了調用方法foo()意味着控件直接傳遞給該方法的默認心智模型)。 AOP是很好,用於記錄或調試等事情,因爲它可以讓你編寫一小段代碼,很少費力地影響很多交叉問題,而且不需要你修改底層應用程序的代碼。你的建議可以根據需要編織,不需要時可以省略。

+0

你知道任何面向方面的庫/擴展,可以讓你這樣做的Java?我認爲方面只談論方法調用/返回等... – aioobe 2010-10-22 16:14:33

+0

是的,這是我一直在尋找。我需要一種方法來用一些代碼「裝飾」一個變量訪問,並且我不能使用getter/setter(或者至少它不是最好的解決方案。謝謝Andrzej – Jack 2010-10-22 16:23:18

+0

@aioobe:[AspectJ](http:// www .eclipse.org/aspectj /)提供'get'和'set'連接點,可用於切入點來檢測字段級別的訪問 – 2010-10-22 16:34:18

3

,我想知道是否可以使用反射,或類似的東西來調用每當變量是在讀取或寫入模式下訪問的方法。

是的。如果使用getter和setter方法正確地封裝數據,則可以將這些代碼放在這些方法中,或者在子類中覆蓋這些方法。

(現在我看到了你的ps) - 不,沒有辦法用反射來解決這個問題。如果我被問到(強迫?)來解決這個問題,我會編寫自己的類加載器,也許使用ASM框架,並用getter/setter方法的適當調用替換每個get-field/set-field指令。

他們實際上有一個常見問題進入了這一點,有一個解決方案:

+0

這比我想象的更「硬核」,但它是一個很好的選擇。謝謝 – Jack 2010-10-22 16:24:21

0

AFAIK,你不能用Java來做。如你所說,使用getters和setter。