0

ロギングの目的で、コードを変更せずに置き換えたいタイプのリストがあります(ロギングの部分は散発的に使用するだけです)。実行時にクラスフィールドが変更されたとき、またはクラスのソースコード(LinkedListなど)がないときを知るために、クラスフィールドのプロキシを簡単に作成する方法を探しています。クラスメソッドが呼び出されたとき。

例として、自分に属するクラスであるこのコードがあり、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を変更するたびに、知る必要があります。リスト参照はパラメータによってどこにでも渡すことができるので、ソリューションを完全にコード分析で行うべきではないと思います。myListLinkedListgetMyList()

この場合、ログは、フィールドがプリミティブであるかオブジェクトであるかに関係なく、フィールド専用です。コードがないタイプ(LinkedListなど)の場合、メソッドが呼び出されたとき、またはメソッドが読み取られたり書き込まれたりするパブリックフィールドが通知されたら、喜んでいます。

4

2 に答える 2

3

おそらく、これらのイベントを接続するために AspectJ を使用できます...いつ接続できるかについては、ポイントカットを参照しください。

または、CGLib またはその他のバイトコード ライブラリを使用して、読み込み時にバイトコードを変更し、フィールド アクセス時にアクセス カウンターをインクリメントするなどの追加ロジックを挿入します。

または、必要なコードを織り込むためにLombokを拡張します。(これは、プレーンな Java バイトコードを変更するよりも簡単であることがわかりました)。これはコンパイル時になります

于 2013-01-02T13:08:12.793 に答える
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);
    }
}

ご覧のとおり、発信者はリストを変更できないため、変更が発生したときに通知を受ける必要はありません。呼び出し元がリストを変更したい場合は、メソッドの 1 つを呼び出す必要があります。この場合、変更を認識できます。

クラスのソース コード (LinkedList など) がありません。

アクセスできますが、変更しないでください。(本当にやりたいならそうしてもいい)

代わりに、変更したメソッドを変更するコレクションをサブクラス化できます。ただし、不変のコレクションを返すことをお勧めします。

于 2013-01-02T13:12:26.183 に答える