gson原理

本文详细介绍了Gson库中自定义类型适配器的使用,包括JsonAdapter、TypeAdapter、TypeAdapterFactory的实现,以及如何处理空值、数组和异常情况。通过自定义TypeAdapter,可以灵活控制JSON数据与Java对象之间的转换,提高序列化和反序列化的效率和准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@JsonAdapter(UserJsonAdapter.class) 自定义解析类继承TypeAdapter<> 需要重写read跟write   write是把对象写成字符串,read是把字符串写成对象

 

 

 

 

几种用法: (1)调用反射的TypeAdapter 耗性能

 public static void test1() {
        //基本使用
        //反射的TypeAdapter 耗性能
        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .serializeNulls().create();
        Foo foo = new Foo();
        String json = gson.toJson(foo);
        System.out.println(json);
    }

(2)自定义TypeAdapter

TypeAdapter

JsonReader

JsonWriter

Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class
        , new TypeAdapter<Foo>() {

            @Override
            public void write(JsonWriter out, Foo value) throws IOException {
                if (value == null) {//进行非空判断
                    out.nullValue();
                    return;
                }
                //把Food对象制定成你自己定义的格式的字符串进行输出:不一定是json格式了,就看你怎么组织
                out.beginObject();
                out.name("s").value(value.s+"sdfas");
                out.name("i").value(value.i);
                out.endObject();
            }

            @Override
            public Foo read(JsonReader in) throws IOException {
                if (in.peek() == JsonToken.NULL) {//进行非空判断
                    in.nextNull();
                    return null;
                }
                //读取json串并封装成Foo对象返回之
                final Foo foo = new Foo();
                in.beginObject();
                while (in.hasNext()) {
                    switch (in.nextName()) {
                        case "s":
                            foo.s = in.nextString();
                            break;
                        case "i":
                            foo.i = in.nextInt();
                            break;
                    }
                }
                in.endObject();
                return foo;
            }
        }).create();

Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);

 

//如果不判断非空处理的话也可以.nullSafe() 系统自动帮你处理

 public static void test3() {
        //nullSafe()演示
        Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class
                , new TypeAdapter<Foo>() {

                    @Override
                    public void write(JsonWriter out, Foo value) throws IOException {
                        out.beginObject();
                        out.name("s").value(value.s);
                        out.name("i").value(value.i);
                        out.endObject();
                    }

                    @Override
                    public Foo read(JsonReader in) throws IOException {
                        //读取json串并封装成Foo对象返回之
                        final Foo foo = new Foo();
                        in.beginObject();
                        while (in.hasNext()) {
                            switch (in.nextName()) {
                                case "s":
                                    foo.s = in.nextString();
                                    break;
                                case "i":
                                    foo.i = in.nextInt();
                                    break;
                            }
                        }
                        in.endObject();
                        return foo;
                    }
                }.nullSafe()).create();
        Foo foo = new Foo();
        String json = gson.toJson(foo);
        System.out.println(json);
    }

}

//遇到穿null数组的有两种解决办法一种是自定义TypeAdapter

  public static void test2() {
        //TODO:
        String json = "{\n" +
                "    \"name\": \"java\",\n" +
                "    \"authors\": \"\"\n" +
                "}";
        Gson gson = new Gson();
        GsonError1 gsonError1 = gson.fromJson(json, GsonError1.class);

        System.out.println(gsonError1);
    }

另一种实现JsonDeserializer 反序列化接口

static class GsonError1Deserializer implements JsonDeserializer<GsonError1> {

        @Override
        public GsonError1 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            final JsonObject jsonObject = json.getAsJsonObject();

            final JsonElement jsonTitle = jsonObject.get("name");
            final String name = jsonTitle.getAsString();

            JsonElement jsonAuthors = jsonObject.get("authors");

            GsonError1 gsonError1 = new GsonError1();

            if (jsonAuthors.isJsonArray()) {//如果数组类型,此种情况是我们需要的
                //关于context在文章最后有简单说明
                GsonError1.AuthorsBean[] authors = context.deserialize(jsonAuthors, GsonError1.AuthorsBean[].class);
                gsonError1.setAuthors(Arrays.asList(authors));
            } else {//此种情况为无效情况
                gsonError1.setAuthors(null);
            }
            gsonError1.setName(name);
            return gsonError1;
        }
    }

 

 

JsonElement

该类是一个抽象类,代表着json串的某一个元素。这个元素可以是一个Json(JsonObject)、可以是一个数组(JsonArray)、可以是一个Java的基本类型(JsonPrimitive)、当然也可以为null(JsonNull);JsonObject,JsonArray,JsonPrimitive,JsonNull都是JsonElement这个

抽象类的

 

 

{

"key": "value",

"arrays": []

}

例如这个最外层是一个JsonObject vale是一个JsonPrimitive  []是一个JsonArray 每一个元素都是一个JsonElement

TypeAdapters

 

 这个类中定义了几乎所有的基础类型的TypeAdapter和Factory,我们现在挑出一个来研究一下。这是一个URL对象的JSON转换器啦。

public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
    @Override
    public URL read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return null;
      }
      String nextString = in.nextString(); //读出in中的内容
      return "null".equals(nextString) ? null : new URL(nextString);//根据读出的内容,创建URL对象
    }
    @Override
    public void write(JsonWriter out, URL value) throws IOException {
      out.value(value == null ? null : value.toExternalForm()); //写入内容
    }
  };

  public static final TypeAdapterFactory URL_FACTORY = newFactory(URL.class, URL);//创建Facotry啦

 我们可以看到,这是一个URL的转换器

也就是说一种类型对应着一种TypeAdapters

 

如果说这个类是没有的,要么自己自定义TypeAdapters去解析要么系统会调用反射的ReflectiveTypeAdapter去解析

 

TypeAdapterFactory

 这是一个接口,自定义了一个函数:<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type);,具体的实现方法,每一个TypeAdapter都由它生产出来

 

TypeToken

获取gson泛型解析T的类型

 

Gson流程图

newGnos的时候的参数

Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
    final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
    boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
    boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
    LongSerializationPolicy longSerializationPolicy,
    List<TypeAdapterFactory> typeAdapterFactories) {
  this.constructorConstructor = new ConstructorConstructor(instanceCreators);//实例构造器
  this.serializeNulls = serializeNulls;//序列化空
  this.generateNonExecutableJson = generateNonExecutableGson;//生成不可执行前缀(用来防止攻击)
  this.htmlSafe = htmlSafe;//html转义
  this.prettyPrinting = prettyPrinting;//缩进打印
  this.lenient = lenient;//宽松的容错性
//TypeAdapte的工厂列表  最先添加的优先级更高
  List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
//以下都是往工厂列表加入TypeAdapterFactory
//构建不能被重载的TypeAdapter
  // built-in type adapters that cannot be overridden
  factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
  factories.add(ObjectTypeAdapter.FACTORY);

  // the excluder must precede all adapters that handle user-defined types
  factories.add(excluder);
//用户自定义的TypeAdapter工厂
  // user's type adapters
  factories.addAll(typeAdapterFactories);
//以下为默认的TypeAdapter
  // type adapters for basic platform types
  factories.add(TypeAdapters.STRING_FACTORY);
  factories.add(TypeAdapters.INTEGER_FACTORY);
  factories.add(TypeAdapters.BOOLEAN_FACTORY);
  factories.add(TypeAdapters.BYTE_FACTORY);
  factories.add(TypeAdapters.SHORT_FACTORY);
  TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
  factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
  factories.add(TypeAdapters.newFactory(double.class, Double.class,
          doubleAdapter(serializeSpecialFloatingPointValues)));
  factories.add(TypeAdapters.newFactory(float.class, Float.class,
          floatAdapter(serializeSpecialFloatingPointValues)));
  factories.add(TypeAdapters.NUMBER_FACTORY);
  factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
  factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
  factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
  factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
  factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
  factories.add(TypeAdapters.CHARACTER_FACTORY);
  factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
  factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
  factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
  factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
  factories.add(TypeAdapters.URL_FACTORY);
  factories.add(TypeAdapters.URI_FACTORY);
  factories.add(TypeAdapters.UUID_FACTORY);
  factories.add(TypeAdapters.CURRENCY_FACTORY);
  factories.add(TypeAdapters.LOCALE_FACTORY);
  factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
  factories.add(TypeAdapters.BIT_SET_FACTORY);
  factories.add(DateTypeAdapter.FACTORY);
  factories.add(TypeAdapters.CALENDAR_FACTORY);
  factories.add(TimeTypeAdapter.FACTORY);
  factories.add(SqlDateTypeAdapter.FACTORY);
  factories.add(TypeAdapters.TIMESTAMP_FACTORY);
  factories.add(ArrayTypeAdapter.FACTORY);
  factories.add(TypeAdapters.CLASS_FACTORY);
//复合的TypeAdapter
  // type adapters for composite and user-defined types
  factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
  factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
  factories.add(new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor));
  factories.add(TypeAdapters.ENUM_FACTORY);
  factories.add(new ReflectiveTypeAdapterFactory(//最后添加反射机制用的factory
      constructorConstructor, fieldNamingPolicy, excluder));

  this.factories = Collections.unmodifiableList(factories);
}

 

excluder 排除器 处理一些不需要序列化的东西 @Expose 注解等

public final class Excluder implements TypeAdapterFactory, Cloneable {
  private static final double IGNORE_VERSIONS = -1.0d;
  public static final Excluder DEFAULT = new Excluder();

  private double version = IGNORE_VERSIONS;
  private int modifiers = Modifier.TRANSIENT | Modifier.STATIC;
  private boolean serializeInnerClasses = true;
  private boolean requireExpose;
  private List<ExclusionStrategy> serializationStrategies = Collections.emptyList();
  private List<ExclusionStrategy> deserializationStrategies = Collections.emptyList();

  @Override protected Excluder clone() {
    try {
      return (Excluder) super.clone();
    } catch (CloneNotSupportedException e) {
      throw new AssertionError(e);
    }
  }

  public Excluder withVersion(double ignoreVersionsAfter) {
    Excluder result = clone();
    result.version = ignoreVersionsAfter;
    return result;
  }

  public Excluder withModifiers(int... modifiers) {  //static transient 也不会序列化
    Excluder result = clone();
    result.modifiers = 0;
    for (int modifier : modifiers) {
      result.modifiers |= modifier;
    }
    return result;
  }

.......

  @Expose
    private String firstName;//参与序列化(JAVA对象转为JSON)/反序列化(JSON转为JAVA对象)

    @Expose(serialize = false)
    private String lastName;//参与反序列化

    @Expose(serialize = false, deserialize = true)
    private String emailAddress; //不参与

    private String password;//不参与

 

@Since(1.0) private String emailAddress; //当前版本>=1.0时才会参与序列化/反序列化,否则忽略
@Since(1.1) private String password;//当前版本>=1.0时才会参与序列化/反序列化,否则忽略

 

@Until(1.1) private String emailAddress;//当前版本<=1.1时参加序列化/反序列化
@Until(1.1) private String password;//当前版本<=1.1时参加序列化/反序列化

FieldNamingStrategy 字段命名策略  处理这些

@SerializedName("name") //a => name   key为name
        String a;
@SerializedName(value = "name1", alternate = {"name2", "name3"}) //第一个
String b;

ConstructorConstructor 构造器  (用到反射的TypeAdapter才需要使用构造器,使用自定义的不需要,因为类可以直接new出来)

public final class ConstructorConstructor {
  private final Map<Type, InstanceCreator<?>> instanceCreators;

  public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators) {
    this.instanceCreators = instanceCreators;
  }
//通过实例返回一个构造器
  public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
    final Type type = typeToken.getType();
    final Class<? super T> rawType = typeToken.getRawType();

    // first try an instance creator
//首先从集合中取看有没有相同的Type,有就创造实例并返回
    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type);
    if (typeCreator != null) {
      return new ObjectConstructor<T>() {
        @Override public T construct() {
          return typeCreator.createInstance(type);
        }
      };
    }
//然后根据原始类型取,去集合中取
    // Next try raw type match for instance creators
    @SuppressWarnings("unchecked") // types must agree
    final InstanceCreator<T> rawTypeCreator =
        (InstanceCreator<T>) instanceCreators.get(rawType);
    if (rawTypeCreator != null) {
      return new ObjectConstructor<T>() {
        @Override public T construct() {
          return rawTypeCreator.createInstance(type);
        }
      };
    }

........

 

顺序

jsonstr --->排除器--->自定义TypeAdapter --->gson自带的TypeAdapter--->反射 RefctiveTypeAdapter

调用toJson方法

toJson
gson.toJson();
public String toJson(Object src) {
  if (src == null) {
    return toJson(JsonNull.INSTANCE);
  }
  return toJson(src, src.getClass());
}

 

public String toJson(JsonElement jsonElement) {
  StringWriter writer = new StringWriter();
  toJson(jsonElement, writer);
  return writer.toString();
}

最终调用这个方法通过

public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
  boolean oldLenient = writer.isLenient();
  writer.setLenient(true);
  boolean oldHtmlSafe = writer.isHtmlSafe();
  writer.setHtmlSafe(htmlSafe);
  boolean oldSerializeNulls = writer.getSerializeNulls();
  writer.setSerializeNulls(serializeNulls);
  try {
    Streams.write(jsonElement, writer);//实际上是TypeAdapter
  } catch (IOException e) {
    throw new JsonIOException(e);
  } finally {
    writer.setLenient(oldLenient);
    writer.setHtmlSafe(oldHtmlSafe);
    writer.setSerializeNulls(oldSerializeNulls);
  }
}

JsonWriter里面比较重要的方法

/**
 * Encodes {@code value}.
 *
 * @param value the literal string value, or null to encode a null literal.
 * @return this writer.
 */
public JsonWriter value(String value) throws IOException {
  if (value == null) {
//nullValue()方法会在value值的地方存入一个null
    return nullValue();
  }
//这一方法将之前保存在deferredName 中的字符串写入到writer中
//方法中处理会加逗号,将deferredName变量清空等问题
//核心是调用string(...)方法写入
  writeDeferredName();
//更新stack指令
  beforeValue();
//和上方写入deferredName一样,此处调用写入value
  string(value);
  return this;
}

//字符串的操作

private void string(String value) throws IOException {
  String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
  out.write('\"');
  int last = 0;
  int length = value.length();
  for (int i = 0; i < length; i++) {
    char c = value.charAt(i);
    String replacement;
    if (c < 128) {
      replacement = replacements[c];
      if (replacement == null) {
        continue;
      }
    } else if (c == '\u2028') {
      replacement = "\\u2028";
    } else if (c == '\u2029') {
      replacement = "\\u2029";
    } else {
      continue;
    }
    if (last < i) {
      out.write(value, last, i - last);
    }
    out.write(replacement);
    last = i + 1;
  }
  if (last < length) {
    out.write(value, last, length - last);
  }
  out.write('\"');
}

private void newline() throws IOException {
  if (indent == null) {
    return;
  }

  out.write('\n');
  for (int i = 1, size = stackSize; i < size; i++) {
    out.write(indent);
  }
}

 

JsonReader doPeek

 

 

 

fromJson

 

public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
  boolean isEmpty = true;
  boolean oldLenient = reader.isLenient();
//打开reader的标准化检验
  reader.setLenient(true);
  try {
//此处相当于调用了一次JsonReader中的doPeek()方法
    reader.peek();//读取一部分拿出来
    isEmpty = false;
//TypeToken本质上是Class的增强型封装类
    TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
//根据TypeToken获取相应的能够处理的TypeAdapter
    TypeAdapter<T> typeAdapter = getAdapter(typeToken);
//反射创建object 都没有换取都合适的就会用到反射
    T object = typeAdapter.read(reader);
    return object;
  } catch (EOFException e) {
    /*
     * For compatibility with JSON 1.5 and earlier, we return null for empty
     * documents instead of throwing.
     */
    if (isEmpty) {
      return null;
    }
    throw new JsonSyntaxException(e);
  } catch (IllegalStateException e) {
    throw new JsonSyntaxException(e);
  } catch (IOException e) {
    // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
    throw new JsonSyntaxException(e);
  } catch (AssertionError e) {
    AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
    error.initCause(e);
    throw error;
  } finally {
    reader.setLenient(oldLenient);
  }
}

//获取对应的适配器

public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {

//typeTokenCache 是Gson中的一个map对象,用于存储TypeAdapter
//typeTokenCache是一个Gson中各个线程共用的一个缓存池
  TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
  if (cached != null) {
//如果本身就有存储了,就直接返回
    return (TypeAdapter<T>) cached;
  }
//calls是一个TreadLocal对象
//TreadLocal是Gson中单个线程使用的缓存池,在里面存入的对象会在finally代码块中清空掉
  Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
//判断是否需要清空TreadLocal
  boolean requiresThreadLocalCleanup = false;
  if (threadCalls == null) {
    threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
    calls.set(threadCalls);
//这里存入了对象,所以需要清空TreadLocal
    requiresThreadLocalCleanup = true;
  }
//如果存在对象,就会在这里取出来并返回
//FutureTypeAdapter是一个门面模式的应用,其实本质是使用内部的TypeAdapter去处理业务
//如果内部没有存入实际处理业务的TypeAdapter,就会报错
  // the key and value type parameters always agree
  FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
  if (ongoingCall != null) {
    return ongoingCall;
  }

  try {
    FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
    threadCalls.put(type, call);
//这个方法的主体是这个for循环,用于从Gson初始化的时候储存的列表中获取到对应的TypeAdapter
    for (TypeAdapterFactory factory : factories) {
//TypeAdapter的create(...)方法用于对于不是对应类型的参数会返回null
      TypeAdapter<T> candidate = factory.create(this, type);
      if (candidate != null) {
//在此处会存入业务处理的TypeAdapter
        call.setDelegate(candidate);
        typeTokenCache.put(type, candidate);
//在此处存入公共缓存
        return candidate;
      }
    }
    throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
  } finally {
//清楚ThreadLocal缓存
    threadCalls.remove(type);

    if (requiresThreadLocalCleanup) {
      calls.remove();
    }
  }
}

peek方法分析

public JsonToken peek() throws IOException {
  int p = peeked;
  if (p == PEEKED_NONE) {
    p = doPeek();
  }

  switch (p) {
  case PEEKED_BEGIN_OBJECT:
    return JsonToken.BEGIN_OBJECT;
  case PEEKED_END_OBJECT:
    return JsonToken.END_OBJECT;
  case PEEKED_BEGIN_ARRAY:
    return JsonToken.BEGIN_ARRAY;
  case PEEKED_END_ARRAY:
    return JsonToken.END_ARRAY;
  case PEEKED_SINGLE_QUOTED_NAME:
  case PEEKED_DOUBLE_QUOTED_NAME:
  case PEEKED_UNQUOTED_NAME:
    return JsonToken.NAME;
  case PEEKED_TRUE:
  case PEEKED_FALSE:
    return JsonToken.BOOLEAN;
  case PEEKED_NULL:
    return JsonToken.NULL;
  case PEEKED_SINGLE_QUOTED:
  case PEEKED_DOUBLE_QUOTED:
  case PEEKED_UNQUOTED:
  case PEEKED_BUFFERED:
    return JsonToken.STRING;
  case PEEKED_LONG:
  case PEEKED_NUMBER:
    return JsonToken.NUMBER;
  case PEEKED_EOF:
    return JsonToken.END_DOCUMENT;
  default:
    throw new AssertionError();
  }
}

 

int doPeek() throws IOException {
//stack是一个定义在JsonReader中的int数组,作为JsonReader的指令集存在,用于控制变量peeked的状态
//在JsonReader初始化的时候会将stack的第一个元素变成6,其余均为0
//6的意思根据官方注释为"No object or array has been started"(还没开始读取对象或列表)
//6座位常量保存在JsonScope中,JsonScope中好保存了很多代表指令的常量,下列会用到
//stackSize是stack的有效元素计数器,初始化时stackSize=1,即只有一个元素是有效的
  int peekStack = stack[stackSize - 1];
  if (peekStack == JsonScope.EMPTY_ARRAY) {
    stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY;
  } else if (peekStack == JsonScope.NONEMPTY_ARRAY) {
//在第一次调用nextNonWhitespace(true)方法的时候,json字符串会被转换存为一个char数组
//该方法以int值的形式返回下一个要解析的char对象
    // Look for a comma before the next element.
    int c = nextNonWhitespace(true);
    switch (c) {
//peeked是JsonReader中最重要的用来状态控制的int变量
//peeked喝stack会协同控制JsonReader的逻辑行为
    case ']':
      return peeked = PEEKED_END_ARRAY;//PEEKED_END_ARRAY = 4
    case ';':
//检查标准协议选项,json标准中的符号没有分号
//所以在lenient = false的时候就会报错
      checkLenient(); // fall-through
    case ',':
      break;
    default:
      throw syntaxError("Unterminated array");
    }
  } else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) {
    stack[stackSize - 1] = JsonScope.DANGLING_NAME;
    // Look for a comma before the next element.
    if (peekStack == JsonScope.NONEMPTY_OBJECT) {
      int c = nextNonWhitespace(true);
      switch (c) {
      case '}':
        return peeked = PEEKED_END_OBJECT;
      case ';':
        checkLenient(); // fall-through
      case ',':
        break;
      default:
        throw syntaxError("Unterminated object");
      }
    }
    int c = nextNonWhitespace(true);
    switch (c) {
    case '"':
      return peeked = PEEKED_DOUBLE_QUOTED_NAME;
    case '\'':
      checkLenient();
      return peeked = PEEKED_SINGLE_QUOTED_NAME;
    case '}':
      if (peekStack != JsonScope.NONEMPTY_OBJECT) {
        return peeked = PEEKED_END_OBJECT;
      } else {
        throw syntaxError("Expected name");
      }
    default:
      checkLenient();
      pos--; // Don't consume the first character in an unquoted string.
      if (isLiteral((char) c)) {
        return peeked = PEEKED_UNQUOTED_NAME;
      } else {
        throw syntaxError("Expected name");
      }
    }
  } else if (peekStack == JsonScope.DANGLING_NAME) {
    stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT;
    // Look for a colon before the value.
    int c = nextNonWhitespace(true);
    switch (c) {
    case ':':
      break;
    case '=':
      checkLenient();
      if ((pos < limit || fillBuffer(1)) && buffer[pos] == '>') {
        pos++;
      }
      break;
    default:
      throw syntaxError("Expected ':'");
    }
  } else if (peekStack == JsonScope.EMPTY_DOCUMENT) {
    if (lenient) {
      consumeNonExecutePrefix();
    }
    stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT;
  } else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) {
    int c = nextNonWhitespace(false);
    if (c == -1) {
      return peeked = PEEKED_EOF;
    } else {
      checkLenient();
      pos--;
    }
  } else if (peekStack == JsonScope.CLOSED) {
    throw new IllegalStateException("JsonReader is closed");
  }

  int c = nextNonWhitespace(true);
  switch (c) {
  case ']':
    if (peekStack == JsonScope.EMPTY_ARRAY) {
      return peeked = PEEKED_END_ARRAY;
    }
    // fall-through to handle ",]"
  case ';':
  case ',':
    // In lenient mode, a 0-length literal in an array means 'null'.
    if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {
      checkLenient();
      pos--;
      return peeked = PEEKED_NULL;
    } else {
      throw syntaxError("Unexpected value");
    }
  case '\'':
    checkLenient();
    return peeked = PEEKED_SINGLE_QUOTED;
  case '"':
    return peeked = PEEKED_DOUBLE_QUOTED;
  case '[':
    return peeked = PEEKED_BEGIN_ARRAY;
  case '{':
    return peeked = PEEKED_BEGIN_OBJECT;
  default:
    pos--; // Don't consume the first character in a literal value.
  }

  int result = peekKeyword();
  if (result != PEEKED_NONE) {
    return result;
  }

  result = peekNumber();
  if (result != PEEKED_NONE) {
    return result;
  }

  if (!isLiteral(buffer[pos])) {
    throw syntaxError("Expected value");
  }

  checkLenient();
  return peeked = PEEKED_UNQUOTED;
}

//解析字符串

 

private int nextNonWhitespace(boolean throwOnEof) throws IOException {
  /*
   * This code uses ugly local variables 'p' and 'l' representing the 'pos'
   * and 'limit' fields respectively. Using locals rather than fields saves
   * a few field reads for each whitespace character in a pretty-printed
   * document, resulting in a 5% speedup. We need to flush 'p' to its field
   * before any (potentially indirect) call to fillBuffer() and reread both
   * 'p' and 'l' after any (potentially indirect) call to the same method.
   */
  char[] buffer = this.buffer;
  int p = pos;
  int l = limit;
  while (true) {
    if (p == l) {
      pos = p;
      if (!fillBuffer(1)) {
        break;
      }
      p = pos;
      l = limit;
    }

    int c = buffer[p++];
    if (c == '\n') {
      lineNumber++;
      lineStart = p;
      continue;
    } else if (c == ' ' || c == '\r' || c == '\t') {
      continue;
    }

    if (c == '/') {
      pos = p;
      if (p == l) {
        pos--; // push back '/' so it's still in the buffer when this method returns
        boolean charsLoaded = fillBuffer(2);
        pos++; // consume the '/' again
        if (!charsLoaded) {
          return c;
        }
      }

      checkLenient();
      char peek = buffer[pos];
      switch (peek) {
      case '*':
        // skip a /* c-style comment */
        pos++;
        if (!skipTo("*/")) {
          throw syntaxError("Unterminated comment");
        }
        p = pos + 2;
        l = limit;
        continue;

      case '/':
        // skip a // end-of-line comment
        pos++;
        skipToEndOfLine();
        p = pos;
        l = limit;
        continue;

      default:
        return c;
      }
    } else if (c == '#') {
      pos = p;
      /*
       * Skip a # hash end-of-line comment. The JSON RFC doesn't
       * specify this behaviour, but it's required to parse
       * existing documents. See http://b/2571423.
       */
      checkLenient();
      skipToEndOfLine();
      p = pos;
      l = limit;
    } else {
      pos = p;
      return c;
    }
  }
  if (throwOnEof) {
    throw new EOFException("End of input" + locationString());
  } else {
    return -1;
  }
}

 

直接ReflectiveTypeAdapterFactory反射分析流程

 

@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) {
  Class<? super T> raw = type.getRawType();

  if (!Object.class.isAssignableFrom(raw)) {
    return null; // it's a primitive!
  }

  ObjectConstructor<T> constructor = constructorConstructor.get(type);//首先根据类型获取到构造器
  return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}

TypeToken//相当于拿到一个类下面所有的变量字段

//这个方法用于把bean类的字段搜集

private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
  Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();//创建一个Map结构,存放所有的BoundField
  if (raw.isInterface()) {
    return result;
  }

  Type declaredType = type.getType();
  while (raw != Object.class) {//如果类型是Object则结束循环
    Field[] fields = raw.getDeclaredFields();//获取该类型的所有的内部属性
    for (Field field : fields) {
      boolean serialize = excludeField(field, true);
      boolean deserialize = excludeField(field, false);
      if (!serialize && !deserialize) {
        continue;
      }
      accessor.makeAccessible(field);
      Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
      List<String> fieldNames = getFieldNames(field);//获取该Filed的名字(Gson通过注解可以给一个属性)
      BoundField previous = null;
      for (int i = 0, size = fieldNames.size(); i < size; ++i) {
//多个解析名,第一作为默认的序列化名称
        String name = fieldNames.get(i);
        if (i != 0) serialize = false; // only serialize the default name
//创建BoundField
//根据filed,type,以及是否支持序列化和反序列化来创建一个BoundField对象
        BoundField boundField = createBoundField(context, field, name,
            TypeToken.get(fieldType), serialize, deserialize);
//讲BoundField放入Map中,获取将替换的value(如果有的话)
//讲属性名称作为key,boundField作为vale保存到result中
        BoundField replaced = result.put(name, boundField);

//如果之前解析过对应的这个值的话,这里就会导致previous不为空,从而报错
        if (previous == null) previous = replaced;
      }
//做好记录
      if (previous != null) {
        throw new IllegalArgumentException(declaredType
            + " declares multiple JSON fields named " + previous.name);
      }
    }
    type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
    raw = type.getRawType();
  }
  return result;
}

 

private ReflectiveTypeAdapterFactory.BoundField createBoundField(
    final Gson context, final Field field, final String name,
    final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
//是否是原始数据类型(int,boolean,float..)
  final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
  // special casing primitives here saves ~5% on Android...
  JsonAdapter annotation = field.getAnnotation(JsonAdapter.class);
  TypeAdapter<?> mapped = null;
  if (annotation != null) {
//Gson尝试获取该类型的TypeAdapter
    mapped = jsonAdapterFactory.getTypeAdapter(
        constructorConstructor, context, fieldType, annotation);
  }
  final boolean jsonAdapterPresent = mapped != null;
//获取当前json串的一个name/value对应JavaBean里面的变量类型type,或者这个type对应的TypeAdapter类
  if (mapped == null) mapped = context.getAdapter(fieldType);//获取对应的基本类型
//final变量,便于内部类使用
  final TypeAdapter<?> typeAdapter = mapped;
  return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) {
    @SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree
    @Override void write(JsonWriter writer, Object value)
        throws IOException, IllegalAccessException {
      Object fieldValue = field.get(value);
      TypeAdapter t = jsonAdapterPresent ? typeAdapter
          : new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType());
      t.write(writer, fieldValue);
    }

//ReflectiveTypeAdapter委托的Json读操作会调用到这里
    @Override void read(JsonReader reader, Object value)
        throws IOException, IllegalAccessException {、
//通过该属性的类型对应的TypeAdapter尝试读取json串
//如果是基础类型,则直接读取,
//如果是复合类型则递归之前的流程
      Object fieldValue = typeAdapter.read(reader);//获取下一个jsontoken而不消耗它
      if (fieldValue != null || !isPrimitive) {
        field.set(value, fieldValue);//更新filed值
      }
    }
    @Override public boolean writeField(Object value) throws IOException, IllegalAccessException {
      if (!serialized) return false;
      Object fieldValue = field.get(value);
      return fieldValue != value; // avoid recursion for example for Throwable.cause
    }
  };
}

 

 

return new Adapter<T>(constructor, getBoundFields(gson, type, raw));new Adapte的时候调用read方法

 

Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
  this.constructor = constructor;
  this.boundFields = boundFields;
}

@Override public T read(JsonReader in) throws IOException {
  if (in.peek() == JsonToken.NULL) {
    in.nextNull();
    return null;
  }

  T instance = constructor.construct();

  try {
    in.beginObject();
    while (in.hasNext()) {
      String name = in.nextName();.//开始逐个读取json串中的key
      BoundField field = boundFields.get(name);//通过key寻找对应的属性
      if (field == null || !field.deserialized) {
        in.skipValue();
      } else {
        field.read(in, instance);
      }
    }
  } catch (IllegalStateException e) {
    throw new JsonSyntaxException(e);
  } catch (IllegalAccessException e) {
    throw new AssertionError(e);
  }
  in.endObject();
  return instance;
}

 

@Override void read(JsonReader reader, Object value)//ReflectiveTypeAdapter中上面使用到的
    throws IOException, IllegalAccessException {
  Object fieldValue = typeAdapter.read(reader);
  if (fieldValue != null || !isPrimitive) {
    field.set(value, fieldValue);
  }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值