Gson全解析之二:JsonReader的其它方法

上篇文章的示例代码

String json = "{\"name\":\"王成wisely\",\"age\":\"24\"}";
private void readJson2User(){
    User user = new User();
    StringReader reader = new StringReader(json);
    JsonReader jsonReader = new JsonReader(reader);
    try {
        jsonReader.beginObject();
        while (jsonReader.hasNext()){
            String name = jsonReader.nextName();
            switch (name){
                case "name":
                    user.name = jsonReader.nextString();
                    break;
                case "age":
                    user.age = jsonReader.nextInt();
                    break;
            }

        }
        jsonReader.endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

我们已经说完了beginObject()方法的源码,下面接着按示例代码的调用顺序来分析一下JsonReader的其它方法。

hasNext()


public boolean hasNext() throws IOException {
  int p = peeked;
  if (p == PEEKED_NONE) {
    p = doPeek();
  }
  return p != PEEKED_END_OBJECT && p != PEEKED_END_ARRAY;
}

在上一篇的最后,peeked被赋值为PEEKED_NONE,程序进入到doPeek()方法。

private int doPeek() throws IOException {
    int peekStack = stack[stackSize - 1];
    if (peekStack == JsonScope.EMPTY_ARRAY) {
      stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY;
    } else if (peekStack == JsonScope.NONEMPTY_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_DOUBLE_QUOTED_NAME;
      case '\'':
        ...
      case '}':
        ...
      default:
        ...
      }
    } else if (peekStack == JsonScope.DANGLING_NAME) {
      ...
    } else if (peekStack == JsonScope.EMPTY_DOCUMENT) {
      ...
    } else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) {
      ...
    } else if (peekStack == JsonScope.CLOSED) {
      ...
    }

    int c = nextNonWhitespace(true);
    switch (c) {
    case ']':
      ...
    case ';':
    case ',':
      ...
    case '\'':
      ...
    case '"':
      ...
    case '[':
      return peeked = PEEKED_BEGIN_ARRAY;
    case '{':
      return peeked = PEEKED_BEGIN_OBJECT;
    default:
      pos--; // Don't consume the first character in a literal value.
    }
    ...
    return peeked = PEEKED_UNQUOTED;
  }

第2行,stackSize=2,peekStack=stack[1]=JsonScope.EMPTY_OBJECT。
第8行,stack[1]=JsonScope.DANGLING_NAME;

stack数组 value
stack[0] JsonScope.EMPTY_DOCUMENT JsonScope.NONEMPTY_DOCUMENT
stack[1] JsonScope.EMPTY_OBJECT
stack[1] JsonScope.DANGLING_NAME

第13行

int c = nextNonWhitespace(true);
private int nextNonWhitespace(boolean throwOnEof) throws IOException {
    char[] buffer = this.buffer;
    int p = pos;
    int l = limit;
    while (true) {
      if (p == l) {
        ...
      }

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

      if (c == '/') {
        ...
      } else if (c == '#') {
        ...
      } else {
        pos = p;
        return c;
      }
    }
    ...
  }

直接看第10行

int c = buffer[p++];

int c = buffer[1]=34,在ANSCII码中34就是双引号,p=2。

0 1
{

第24行,pos=p=2,将c作为返回值返回到doPeek()方法中。
doPeek()中运行到第16行

peeked = PEEKED_DOUBLE_QUOTED_NAME;
peeked的值
PEEKED_NONE
PEEKED_BEGIN_OBJECT
PEEKED_NONE
PEEKED_DOUBLE_QUOTED_NAME

程序回到hasNext()方法中

return p != PEEKED_END_OBJECT && p != PEEKED_END_ARRAY

由于p=PEEKED_DOUBLE_QUOTED_NAME,所以hasNext()方法返回true。

nextName()


public String nextName() throws IOException {
    int p = peeked;
    if (p == PEEKED_NONE) {
      p = doPeek();
    }
    String result;
    if (p == PEEKED_UNQUOTED_NAME) {
      result = nextUnquotedValue();
    } else if (p == PEEKED_SINGLE_QUOTED_NAME) {
      result = nextQuotedValue('\'');
    } else if (p == PEEKED_DOUBLE_QUOTED_NAME) {
      result = nextQuotedValue('"');
    } else {
      throw new IllegalStateException("Expected a name but was " + peek()
          + " at line " + getLineNumber() + " column " + getColumnNumber());
    }
    peeked = PEEKED_NONE;
    return result;
  }

根据hasNext()方法可知,p=PEEKED_DOUBLE_QUOTED_NAME,程序运行到第12行,

nextQuotedValue('"');
private String nextQuotedValue(<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值