当一个集合中的值(ArrayList
)被一段未知的代码(ArrayList
实例保持不变)替换为null
时,我遇到了一个错误。在几个事件之后,然后将实际值设置回相同索引处的集合(0
,并且值实例的id相同)。有几个自定义框架可能通过反射访问了集合,我找不到罪魁祸首。
我尝试使用代理和不可修改的列表进行调试,但无济于事。我认为,问题是ArrayList
实例是由一个可能保留对列表的引用的框架创建的。
在我看来,记录集合中发生的所有事情和价值会非常好。我并不仅仅意味着国家的变化,而是从任何地方引用。有没有办法查看对象的生活故事?
答案 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");
}
}