反射修改不可变集合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
    }

进阶参考:https://www.jianshu.com/p/bf2623f18d6a

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值