我正在尝试使用aspectJ访问参数的名称,但我总是得到 arg0 而不是真正的名称。我发现我应该在AspectJ JoinPoint question使用-g参数激活java调试选项,但这对我不起作用...
这是我的java代码:
private Set<Collection<String>> s;
private Collection<String> c;
public HashCodeProperty() {
s = new HashSet<Collection<String>>();
c = new ArrayList<String>();
}
/**
* method that satisfy property
*/
public void satisfy() {
c.add("this is ok");
s.add(c);
System.out.println("Collection is in Set: " + s.contains(c));
}
/**
* method that violate the property
*/
public void violate() {
c.add("this is ok");
s.add(c);
c.add("don't do this");
System.out.println("Collection is in Set: " +s.contains(c));
}
这是我的AspectJ代码:
pointcut addElementsToHashCodeSet() : call (* Set.add(..));
declare warning: addElementsToHashCodeSet(): "pointcut: addElementsToHashCode()";
after(): addElementsToHashCodeSet() {
monitorHashCode.addElementsToHashCode((MethodSignature)thisJoinPoint.getSignature());
public void addElementsToHashCode(MethodSignature methodSignature) {
System.out.println("\naddElementsToHashCode.");
// We need to access to real PARAMETER NAME
// Then we will concatenate with method and full class name
String firstParameterName = methodSignature.getParameterNames()[0];
// Add firstParameterName to an array that will contain all
// the name of the collections inserted into the HasSet
System.out.println("\nfirstParameterName: "+firstParameterName);
}
当前输出:
firstParameterName:arg0
我需要输出的内容:
firstParameterName:c
我有两个选择:
我还需要激活什么?
非常感谢!
答案 0 :(得分:1)
我找到了一种更好的方法来知道变量的名称(标识符),并带有以下切点:
before(Collection c): addElementsToHashCodeSet() && args(c)
通过这种方式,我们可以直接引用变量 c 。
不需要在eclipse中激活调试符号。
可以使用以下代码实现所需的解决方案:
仪器人:
package fr.imag.ufrima.tat.tp6.aspects;
import java.util.Collection;
import java.util.Set;
import fr.imag.ufrima.tat.tp6.aspects.monitor.MonitorHashCode;
/**
* Techniques Avancées de Test
*
* @author Rodmar CONDE
*
* Instrumentator for validation of HashSet classes.
*
* Secures the usage of HashSet that include Collections in preventing
* more elements to be added to the collections once they are added.
*
* Monitor code is provided in a separate class: MonitorHashCode.
*/
public aspect InstrumentationHashCode {
private MonitorHashCode monitorHashCode;
public InstrumentationHashCode() {
monitorHashCode = new MonitorHashCode();
}
pointcut addElementsToHashCodeSet() : call (* Set.add(..));
declare warning: addElementsToHashCodeSet(): "pointcut: addElementsToHashCode()";
before(Collection c): addElementsToHashCodeSet() && args(c) {
monitorHashCode.addElementsToHashCode(c);
}
pointcut addElementsToCollection() : call (* Collection.add(..));
declare warning: addElementsToCollection(): "pointcut: addElementsToCollection()";
after(String s): addElementsToCollection() && args(s) {
monitorHashCode.addElementsToCollection(thisJoinPoint.getTarget());
}
}
监视器:
package fr.imag.ufrima.tat.tp6.aspects.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
*
* @author Rodmar CONDE
*
* Monitor used to prevent adding elements to a collection that has already been added to a HashMap
*
*/
public class MonitorHashCode {
/**
* Stores the system identity hashcode of the collections that are added to the monitored HashCode
*/
private List<Integer> collectionsAddedToHashSet;
public MonitorHashCode() {
System.out.println("Monitor created.");
collectionsAddedToHashSet = new ArrayList<Integer>();
}
/**
* Adds the system identity hashcode of the passed collection to the list
*
* @param c Collection to be added to the list
*/
public void addElementsToHashCode(Collection c) {
System.out.println("\naddElementsToHashCode.");
collectionsAddedToHashSet.add(System.identityHashCode(c));
System.out.println("\nCollection has been added to HashMap.");
}
/**
*
* Before adding the element, search if the collection exists already
* in the list, if so print an error.
*
* @param pointCutTarget
*/
public void addElementsToCollection(Object pointCutTarget) {
System.out.println("\naddElementsToCollection.");
int systemIdentityHashCode = System.identityHashCode(pointCutTarget);
boolean isContained = collectionsAddedToHashSet.contains(systemIdentityHashCode);
System.out.println(String.format("currentCollection: %s systemIdentityHashCode: %d - isContained: %s", pointCutTarget, systemIdentityHashCode, isContained));
if (isContained) {
System.out.println("Error: you have already added this collection into a hashmap, you can not add more elements into it!");
}
}
}
答案 1 :(得分:0)
我读它的方式是你要求Set.add(..) - 方法的第一个参数的(内部)名称。这永远不会是您定义的名称,因为它是Java-API的一部分。您想要的是传递给该参数的值的名称。
这些值应该通过JoinPoint.getArgs()-method以Object []的形式提供,但我不能立即确定如何获取它们的名称。应该可以通过反思来实现。