如何跟踪对象发生的一切?

时间:2017-04-06 07:26:30

标签: java

当一个集合中的值(ArrayList)被一段未知的代码(ArrayList实例保持不变)替换为null时,我遇到了一个错误。在几个事件之后,然后将实际值设置回相同索引处的集合(0,并且值实例的id相同)。有几个自定义框架可能通过反射访问了集合,我找不到罪魁祸首。

我尝试使用代理和不可修改的列表进行调试,但无济于事。我认为,问题是ArrayList实例是由一个可能保留对列表的引用的框架创建的。

在我看来,记录集合中发生的所有事情和价值会非常好。我并不仅仅意味着国家的变化,而是从任何地方引用。有没有办法查看对象的生活故事?

2 个答案:

答案 0 :(得分:0)

你可以覆盖ArrayList最有趣的方法,比如add,addAll,remove如下:

public class MyList<T> extends ArrayList<T> {

// constructors

@Override
public boolean add(T value) {
    // log here
    super.add(value);
    // print stack trace, for example
}

// and so on
}

这不是一个干净的解决方案,但它可能会有所帮助

答案 1 :(得分:0)

使用java.util.Collections.unmodifiableList()将ArrayList更改为UnmodifiableList,然后检查将获得异常的位置。另一种方法是创建一个代理对象,它将代理每个方法调用并记录每次调用。

java代理的示例 - 您需要一个代理接口 - 在此示例中,ArrayList的接口是List。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ProxyTest {
    public static void main(String[] args) {

        final List<Object> list = new ArrayList<>();

        class MyInvocationHandler implements InvocationHandler {

            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("Invoking method: " + method.getName() +", with params: "+Arrays.asList(args));

                return method.invoke(list, args);
            }
        }

        InvocationHandler handler = new MyInvocationHandler();
        List proxy = (List) Proxy.newProxyInstance(List.class.getClassLoader(), new Class[] { List.class }, handler);


        proxy.add("hello");
    }
}