转:
net.sf.json.JSONObject处理 "null" 字符串的一些坑
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28988969/article/details/80168447
添加依赖
<dependency>
<groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency>
- 1
- 2
- 3
- 4
- 5
- 6
示例代码
package com.ahut;
import net.sf.json.JSONObject; import org.junit.Test; import org.springframework.boot.test.context.SpringBootTest; import java.util.Map; @SpringBootTest public class ConfigClientApplicationTests { @Test public void contextLoads() { JSONObject jsonObject = new JSONObject(); jsonObject.put("key", "null"); jsonObject.put("key2", "notNull"); Map itemsMap = (Map) jsonObject; System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull System.out.println(jsonObject.get("key2").getClass());//class java.lang.String System.out.println(itemsMap.get("key").equals("null"));//true System.out.println("null".equals(itemsMap.get("key")));//false System.out.println(itemsMap.get("key2").equals("notNull"));//true System.out.println("notNull".equals(itemsMap.get("key2")));//true } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
运行结果:
class net.sf.json.JSONNull class java.lang.String true false true true
- 1
- 2
- 3
- 4
- 5
- 6
代码分析
net.sf.json.JSONObject本身就实现了Map接口:
public final class JSONObject extends AbstractJSON implements JSON, Map, Comparable { ... }
- 1
- 2
- 3
- 4
其内部维护了一个Map属性,实际就是一个HashMap:
// 成员变量
private Map properties;
// 构造方法
public JSONObject() { this.properties = new ListOrderedMap(); } public ListOrderedMap() { this(new HashMap()); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
注意:
- 非”null”字符串放到JSONObject类中时,取出来使用时是java.lang.String类型
- “null”字符串放到JSONObject类中时,取出来的使用会转换成net.sf.json.JSONNull类型:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package net.sf.json; import java.io.IOException; import java.io.Writer; public final class JSONNull implements JSON { private static JSONNull instance = new JSONNull(); public static JSONNull getInstance() { return instance; } private JSONNull() { } public boolean equals(Object object) { return object == null || object == this || object == instance || object instanceof JSONObject && ((JSONObject)object).isNullObject() || "null".equals(object); } public int hashCode() { return 37 + "null".hashCode(); } public boolean isArray() { return false; } public boolean isEmpty() { throw new JSONException("Object is null"); } public int size() { throw new JSONException("Object is null"); } public String toString() { return "null"; } public String toString(int indentFactor) { return this.toString(); } public String toString(int indentFactor, int indent) { StringBuffer sb = new StringBuffer(); for(int i = 0; i < indent; ++i) { sb.append(' '); } sb.append(this.toString()); return sb.toString(); } public Writer write(Writer writer) { try { writer.write(this.toString()); return writer; } catch (IOException var3) { throw new JSONException(var3); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
这就是为什么:
System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull System.out.println(jsonObject.get("key2").getClass());//class java.lang.String
- 1
- 2
- 3
itemsMap.get(“key”).equals(“null”)
分析:
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", "null"); Map itemsMap = (Map) jsonObject; System.out.println(itemsMap.get("key").equals("null"));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
键为 “key” 的值对应 “null” 字符串
所以itemsMap.get(“key”)获取到的类型是JSONNull
所以itemsMap.get(“key”).equals(“null”)中的equals调用的是JSONNull中的equals方法
public boolean equals(Object object) {
return object == null || object == this || object == instance || object instanceof JSONObject && ((JSONObject)object).isNullObject() || "null".equals(object); }
- 1
- 2
- 3
所以:
System.out.println(itemsMap.get("key").equals("null"));//true
- 1
“null”.equals(itemsMap.get(“key”))
分析:
JSONObject jsonObject = new JSONObject();
jsonObject.put("key", "null"); Map itemsMap = (Map) jsonObject; System.out.println("null".equals(itemsMap.get("key")));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
此时”null”.equals(itemsMap.get(“key”))调用的equals是String类的equals方法:
/**
* String复写的equals方法
*/
public boolean equals(Object anObject) {
// 比较地址是否相同,两个应用指向同一个对象(同一个地址) if (this == anObject) { return true; } // 判断是否是String类 if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } // 返回结果 return false; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
执行分析:
- itemsMap.get(“key”)获取到的是net.sf.json.JSONNull类型
- net.sf.json.JSONNull和”null”不是同一个对象,继续向下执行
- net.sf.json.JSONNull不是String类型,继续向下执行
- return false
所以:
System.out.println("null".equals(itemsMap.get("key")));//false