前两弹说了JSONObject存储结构是一个HashMap,都是一些字符串的解析操作,代码容易理解。输出视觉友好的JSON文本,可以这样写:
public class JSONObjectTest {
public static void main(String[] a){
String json = "{china:{hubei:[wuhan,yichang],hunan: changsha},status:1}";
JSONObject jsonObject = new JSONObject(json);
System.out.println(jsonObject.toString(4));
}
}
输出为:
{
"china": {
"hubei": [
"wuhan",
"yichang"
],
"hunan": "changsha"
},
"status": 1
}
结果中带了换行和缩进,下面看toString(...)方法:
@Override
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
//重载方法,indentFactor是视觉上相对上一级缩进空格数
public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter();
//获取最终存文本信息的StringBuffer对象
synchronized (w.getBuffer()) {
return this.write(w, indentFactor, 0).toString();
}
}
JSONObject对象转字符串就是在写一个StringBuffer对象,将对象中的基本类型等信息合适的打印出。下面看public Writer write(Writer writer, int indentFactor, int indent):
//最后内容都在writer对象里,indentFactor是相对上一级缩进空格数,toString(...)方法调用时传的indent为0
public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException {
try {
//commanate == true标记取完一个value,用于加上','和换行
boolean commanate = false;
final int length = this.length();
writer.write('{');
//只有一个key时不换行
if (length == 1) {
final Entry<String,?> entry = this.entrySet().iterator().next();
final String key = entry.getKey();
//输出的key都带有引号,字符串value也带
//quote(key)这个方法给字符串加引号,让转义字符、等合理的打印出
writer.write(quote(key));
writer.write(':');
if (indentFactor > 0) {
writer.write(' ');
}
try{
writeValue(writer, entry.getValue(), indentFactor, indent);
} catch (Exception e) {
throw new JSONException("Unable to write JSONObject value for key: " + key, e);
}
} else if (length != 0) { //缩进时
//indent是上一级的缩进量,JSONObject等中比上一级多缩进一个indentFactor
final int newindent = indent + indentFactor;
for (final Entry<String,?> entry : this.entrySet()) {
if (commanate) {
writer.write(',');
}
if (indentFactor > 0) {
writer.write('\n'); //换行
}
indent(writer, newindent); //填充newindent数量空格
final String key = entry.getKey();
writer.write(quote(key));
writer.write(':');
if (indentFactor > 0) {
writer.write(' ');
}
try {
//写value,value可以是基本类型、JSONObject、JSONArray等
writeValue(writer, entry.getValue(), indentFactor, newindent);
} catch (Exception e) {
throw new JSONException("Unable to write JSONObject value for key: " + key, e);
}
commanate = true; //换行
}
if (indentFactor > 0) {
writer.write('\n');
}
indent(writer, indent); //最后的'}'缩进
}
writer.write('}');
return writer;
} catch (IOException exception) {
throw new JSONException(exception);
}
}
上面只放了设计的关键代码,toString(...)主要点就是在操作一个StringBuffer对象,在何时填充换行和缩进。其他的代码看看就知道,就不一一介绍。JSONObject主要代码就写完了,代码总体设计上比较清晰简洁,足以满足开发中需要的JSON对象的处理。