• net.sf.json.JSONObject处理 "null" 字符串的一些坑


    转:

    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
  • 相关阅读:
    ElasticSearch应用之数据埋点——认识埋点
    WebStorm好用的插件推荐
    mysql身份验证问题
    (一) MySql的安装
    (一)Mongodb的下载与安装
    解决Flask中 request.get_json()接收不到传来的json数据
    docker查看日志记录
    微信小程序右上角胶囊的信息
    linux shell 字符串操作(长度,查找,替换)详解
    Win7下的内置FTP组件的设置详解
  • 原文地址:https://www.cnblogs.com/libin6505/p/10899489.html
Copyright © 2020-2023  润新知