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并更改myList引用的LinkedList. 我认为解决方案不应该完全通过代码分析来完成,因为列表引用可以通过参数传递到任何地方,比如getMyList()

在这种情况下,日志记录仅用于字段,无论它们是原始的还是对象。对于我没有代码的类型(如 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);
    }
}

如您所见,调用者无法修改列表,因此在发生这种情况时无需通知您。如果调用者想要修改列表,它必须调用您的方法之一,在这种情况下您将知道更改。

我没有类源代码(例如 LinkedList),

您可以访问它,只是不应该修改它。(如果你真的想要,你也可以这样做)

相反,您可以将集合子类化,这将修改您更改的任何方法。但是,返回不可变集合是最佳实践。

于 2013-01-02T13:12:26.183 回答