公司项目中经常要使用json作为数据交换格式,在使用Gson时遇到了一个特别奇怪的问题。debug时,在List中看到是有数据的,转成json后却是null。当时我采用的是下面第一种写法
(二)、 ArrayList常用的初始化方法有三种:
1: List<String> strings=new ArrayList<String>(){{
add("1");
add("2");
add("3");
add("4");
add("5");
}};
2:List<String> list= Arrays.asList("a","b","c","d"); //这种方法可以直接把数组转化成list
3:List<String> stringList=new ArrayList<String>();
for (int i = 0; i < 5; i++) {
stringList.add(String.valueOf(i));
} //这种方法是最常用的一种,循环添加进去
(二)、哪这三种方式有什么不同呢?
直接上图
1、可以看到第一种方式生成的对象实际上并不是一个ArrayList(JsonUtil是该java的文件名),而是当前类(JsonUtil)的一个内部类。
2、同理第二种方式生成的是一个Arrays的内部类对象,该类继承自 abstractList
3、第三种生成的才是我们常用的ArrayList
(三)、结果
经错查看Gson源码
Gson.java :
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
writer.setSerializeNulls(serializeNulls);
try {
((TypeAdapter<Object>) adapter).write(writer, src); //这里强转 返回一个匿名内部类,详见下一页源码
} catch (IOException e) {
throw new JsonIOException(e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
}
Excluder.java
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
Class<?> rawType = type.getRawType();
final boolean skipSerialize = excludeClass(rawType, true); //转成json为null的原来在这,详见该方法,true
final boolean skipDeserialize = excludeClass(rawType, false);
if (!skipSerialize && !skipDeserialize) {
return null;
}
return new TypeAdapter<T>() {
/** The delegate is lazily created because it may not be needed, and creating it may fail. */
private TypeAdapter<T> delegate;
@Override public void write(JsonWriter out, T value) throws IOException {
if (skipSerialize) { //true
out.nullValue(); //JsonWrite.write("null")
return;
}
delegate().write(out, value);
}
private TypeAdapter<T> delegate() {
TypeAdapter<T> d = delegate;
return d != null
? d
: (delegate = gson.getDelegateAdapter(Excluder.this, type));
}
};
}
//排除要跳过的
public boolean excludeClass(Class<?> clazz, boolean serialize) {
if (version != Excluder.IGNORE_VERSIONS
&& !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class))) {
return true;
}
if (!serializeInnerClasses && isInnerClass(clazz)) { //根本原因,跳过了内部类
return true;
}
if (isAnonymousOrLocal(clazz)) {
return true;
}
List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies;
for (ExclusionStrategy exclusionStrategy : list) {
if (exclusionStrategy.shouldSkipClass(clazz)) {
return true;
}
}
return false;
}
Gson.java
public String toJson(Object src, Type typeOfSrc) {
StringWriter writer = new StringWriter();
toJson(src, typeOfSrc, writer);
return writer.toString(); //writer=='null'
}
StringWriter.java
public String toString() {
return buf.toString(); //buf=='null'
}