2013-01-02 75 views
0

我有一個我想替換的類型列表,用於日誌記錄目的,但不更改我的代碼(日誌記錄部分它只是用於esporadically)。我正在尋找一種簡單的方法來爲我的類字段創建某種代理,以便在運行時知道我的類字段何時更改,或者當我沒有類源代碼(例如LinkedList)時,當調用類方法時。在編譯/運行時替換Java類型

舉個例子,如果我有這樣的代碼,這是屬於我的一類,我只是需要被警告MyClass的現場狀態的變化:

public class MyClass { 

    private LinkedList<Integer> myList; 

    private int myInteger; 

    public void myMethod() 
    { 
     myInteger = 15; 
     myList = new LinkedList<Integer>(); 
    } 

    public void myOtherMethod() 
    { 
     myList.add(1); 
    } 

    public LinkedList<Integer> getMyList() { 
     return myList; 
    } 
} 

我需要知道,在運行時(但代碼修改可以在編譯時完成),每當有人更改myInteger的值時,將元素添加到myList並將myList更改爲LinkedList。我覺得解決不應完全用代碼分析完成,因爲列表的引用可通過參數到處傳遞給,像getMyList()

在這種情況下,記錄它只是場,wheter他們是原始的或對象。對於沒有代碼的類型(如LinkedList),如果在調用某個方法或讀取或寫入任何公共字段時收到通知,我會很高興。

+1

你的問題是什麼?我不清楚你試圖達到什麼目的,即使我懷疑它不值得讓編譯器爲你做。 –

+0

對不起@PeterLawrey,我現在要改變它 – rnunes

+1

我仍然沒有看到一個問題的'?'。目前還不清楚你爲什麼要做你的建議。一般認爲不好的做法是返回一個將被改變的集合。相反,不可變的副本可以返回以防止這種情況。 –

回答

3

你也許可以用AspectJ進行掛接這些事件......看到pointcuts的相關信息就當它是可能的掛鉤。

或者你使用CGLIB或任何其他字節碼庫修改字節碼的加載時間和注入額外的邏輯,比如增加一個訪問計數器或類似的訪問地址。

或者您擴展Lombok以編織所需的代碼。 (我發現這比修改普通的java字節碼容易)。這將是編譯時間

0

我建議你只返回一個接口(不是一個具體的類)的集合,並使其不可變。

public class MyClass { 
    private final List<Integer> myList = new ArrayList<>(); 
    private int myInteger; 

    public void myMethod() { 
     myInteger = 15; 
    } 

    public void myOtherMethod(int i) { 
     myList.add(i); 
    } 

    public List<Integer> getMyList() { 
     return Collections.unmodifiableList(myList); 
    } 
} 

正如你所看到的,列表不能被調用者修改,所以你不需要在發生這種情況時得到通知。如果主叫方想要修改列表,則必須調用其中一種方法,在這種情況下,您將意識到這些更改。

我沒有類的源代碼(如鏈表),

您可以訪問它,你就不應修改它。 (如果你真的想要,你也可以這樣做)

相反,你可以繼承子集,它將修改你改變的任何方法。但是,返回一個不可變的集合是最佳實踐。

+0

其關於性能分析。建議對示例代碼的更改如下所示:「這是一個緩慢的程序...不要描述它,使用另一個。」...對我沒有多大意義 – wrm

+0

@wrm OP沒有提到在「問題「,或表現或分析。目前還不清楚他是在問什麼。他沒有問過一個具體的問題,所以也許你的思維讀書能力比我的好。 ;) –

+2

它看起來像...或者我只是讀了標籤...... – wrm