gson反序列化对内部类对象的影响

gson反序列化对内部类对象的影响

Posted by CaiJiahe on August 10, 2017

0x01 问题

final class AutoKeys {

	private final Map<AutoKey, AutoKey> map = new HashMap<>();
	
	private final AtomicBoolean dirty = new AtomicBoolean();
	
	AutoKeys(OctetsStream os, int localInitValue, int localStep) {
		...
		if (TStorage.STORAGE_USE_JSON) {
			Gson gson = new Gson();
			Type type = new TypeToken<Collection<AutoKey>>(){}.getType();
			Collection<AutoKey> set = gson.fromJson(os.toString(), type);
			set.forEach(ak -> add(ak));
		}
		...
	}
	
	private void add(AutoKey ak) {
		if (null != map.put(ak, ak))
			throw new IllegalStateException("Duplicate AutoKey Found");
	}
	
	class AutoKey {
		private long update(long value) {
			dirty.set(true);
			...
		}
		
		...
	}
	
	...

}

初始化AutoKeys后,调用map中AutoKey的update方法抛出空指针异常。

	java.lang.NullPointerException
		at limax.zdb.AutoKeys.access$0(AutoKeys.java:21)
		at limax.zdb.AutoKeys$AutoKey.update(AutoKeys.java:85)
		at limax.zdb.AutoKeys$AutoKey.next(AutoKeys.java:113)

0x02 原因

github-01.jpg

从上图可以看到AutoKey的构造函数第一个参数就是AutoKeys对象,但是反序列化的过程只是对内部类AutoKey的对象的成员变量进行赋值,并没有对指向AutoKeys对象的引用赋值,所以在访问AutoKeys对象的成员变量的时候会抛空指针异常(这个gson反序列化可以扩展到其他的反序列化过程)。