反射修改不可变集合UnmodifiableList
项目中会返回不可改变的List值,对他进行操作会报错:例如
List<Student> list = new ArrayList<Student>();
list.add(new Student());
list = Collections.unmodifiableList(list);
System.out.println(list.get(0));
System.out.println(list.add(new Student()));
实际上是Collection内部有一个静态类UnmodifiableRandomAccessList,它继承了Collections.UnmodifiableList<E>继承了Collections.UnmodifiableCollection<E>,并持有一个引用叫做list。在执行set,add,remove等操作的时候会抛出异常。
既然不能通过正常方法修改,考虑根据反射突破一下,由于是静态内部类,需要去找父类中(一直找到Object)名为list的字段。
/**
* 获得名为field的字段
* @Description:如果本身找不到去父类寻找
* @param object
* @param fieldName
* @return Field
* @author luhao
* @since:2019年2月26日 下午4:06:16
*/
public static Field getDeclaredField(Object object, String fieldName){
Field field = null ;
Class<?> clazz = object.getClass() ;
for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
try {
field = clazz.getDeclaredField(fieldName) ;
return field ;
} catch (Exception e) {
//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
}
}
return null;
}
@SuppressWarnings("unchecked")
public static void main(String args[]) throws Exception {
List<Student> list = new ArrayList<Student>();
list.add(new Student());
list = Collections.unmodifiableList(list);
System.out.println("不可变集合的元素数量:" + list.size());//1
Field pro = Utils.getDeclaredField(list, "list");
pro.setAccessible(true);
List<Student> modifyerList = (List<Student>) pro.get(list);
modifyerList.add(new Student());
System.out.println("不可变集合的元素数量:" + list.size());//2
//list.add(new Student());//报错java.lang.UnsupportedOperationException
}