2016-10-21 8 views
0

リストインターフェイス内のメソッドをポイントするクラスを作成したいと思います。これは私のアドバイスにターゲット(リスト)を追加するまで機能しているようです。私は、リストの要素を追加する前後に(例えば)何が変更されたかを見たいと思いますが、私のリストをオブジェクトと同じように渡すことはできません。ここで私はこれまでのところ、これはターゲット(リスト)で実行されませんしているが、それなしで実行しないものです:AspectJのパラメータ化された型は、ターゲットポイントカットをサポートしていません

pointcut addPointCut() : call(boolean List.add(..)); 

before(List<Integer> list) : addPointCut() && target(list) { 
    System.out.println("testing"); 
    for(Object i : list) { 
     System.out.println(i); 
    } 
} 

答えて

0

Nándorの答えは、あなたが見るコンパイラエラーを記述している限り正確です。 、問題は直接にAspectJにではなく、Javaがジェネリックを実装する方法に関連していないすべての

まず:私はさらに少し行くとは、このエラーが発生した理由もを説明したいです。お読みになる前に、type erasureという現象に慣れてください。

まあ、型消去は、JVMの現実であるとtarget()this()ので、コンパイル時ではなく実行時に解決されるので、 - あなたは間接的に両方getTarget()getThis()JoinPointむしろJoinPoint.StaticPartよりの方法であるという事実から、これを結論付けることができます - 何やりたいことができないため、AspectJコンパイラエラーが発生します。ターゲットリストに何が追加されるのかを動的に判断するには、instanceofを使用するだけです。これを行う最もエレガントな方法は、if()ポイントカット式です。ここで

は、いくつかのサンプルコードです:

ドライバアプリケーション:

だから我々は、リストの2種類ともadd(..)呼び出しの2種類を使用して物事はもう少し面白くするとして。目指すのは、add(..)メソッドのシグネチャに関係なく、対応するリストに追加する整数だけを傍受することです。

package de.scrum_master.app; 

import java.util.ArrayList; 
import java.util.List; 

public class Application { 
    public static void main(String[] args) { 
     List<Integer> integers = new ArrayList<>(); 
     integers.add(11); 
     integers.add(0, 22); 
     integers.add(33); 

     List<String> strings = new ArrayList<>(); 
     strings.add("foo"); 
     strings.add(0, "bar"); 
     strings.add("zot"); 
    } 
} 

アスペクト比:

package de.scrum_master.aspect; 

import java.util.List; 

@SuppressWarnings({"rawtypes", "unchecked"}) 
public aspect GenericsAspect { 
    pointcut addPointCut(List list, Object newElement) : 
     !within(GenericsAspect) &&   // avoid stack overflow due to recursion 
     call(* List.add(..)) &&    // intercept all calls to List.add 
     args(.., newElement) &&    // capture last method parameter 
     if(newElement instanceof Integer) && // only capture added int/Integer elements 
     target(list);       // target is a List 

    before(List list, Object newElement) : 
     addPointCut(list, newElement) 
    { 
     System.out.println(thisJoinPoint + " -> new element = " + newElement); 
     for(Object i : list) 
      System.out.println(" " + i); 

     // Type erasure in action: 
     // During runtime there is no such thing as List<Integer>, only a raw List. 
     // Thus, we can easily add a String to a list declared as List<Integer>. 
     list.add("#" + newElement + "#"); 
    } 
} 

コンソールログ:

call(boolean java.util.List.add(Object)) -> new element = 11 
call(void java.util.List.add(int, Object)) -> new element = 22 
    #11# 
    11 
call(boolean java.util.List.add(Object)) -> new element = 33 
    22 
    #11# 
    11 
    #22# 

それ以上の質問?

0

ジェネリックを使用するタイプtarget(...)またはthis(...)ポイントカットではサポートされていないと、コンパイルは、このエラーで失敗します:parameterized types not supported for this and target pointcuts (erasure limitation)。リストから型パラメーターを削除し、期待どおりに動作するはずです。

関連する問題