一个关于jfinal中常用的com.jfinal.plugin.activerecord.Record反序列化的一个问题。
《Effective Java 3nd》第12章“序列化”。
里面举了一个例子,反序列化HashSet实例需要计算其元素的散列码,对于书中例子的100级之深的HashSet实例,反序列化集合会导致hashCode方法被调用超过2^100次,反序列化花费的时间是无限的。
static byte[] bomb() { Set<Object> root = new HashSet<Object>(); Set<Object> s1 = root; Set<Object> s2 = new HashSet<Object>(); for (int i = 0; i < 100; i++) { Set<Object> t1 = new HashSet<Object>(); Set<Object> t2 = new HashSet<Object>(); t1.add("foo");//make t1 unequal to t2 s1.add(t1); s1.add(t2); s2.add(t1); s2.add(t2); s1 = t1; s2 = t2; } return serialize(root);//获得序列化后的byte[] }
类似的使用Map的层级代码:
static byte[] bomb() { Map<String, Object> root = new HashMap<String, Object>(); Map<String, Object> s1 = root; Map<String, Object> s2 = new HashMap<String, Object>(); for (int i = 0; i < 100; i++) { Map<String, Object> t1 = new HashMap<String, Object>(); Map<String, Object> t2 = new HashMap<String, Object>(); t1.put("foo", "abc");//make t1 unequal to t2 s1.put("t1", t1); s1.put("t2", t2); s2.put("t1", t1); s2.put("t2", t2); s1 = t1; s2 = t2; } System.out.println("start"); System.out.println(root.toString()); return serialize(root);//获得序列化后的byte[] }
redis支持直接存取任何支持序列化的对象,com.jfinal.plugin.activerecord.Record也是支持序列化的,因此可以直接存放至redis,是否也潜在的存在类似上述HashSet的这种反序列化问题呢?