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

添加依赖

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>

示例代码

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
    }

}

运行结果:

class net.sf.json.JSONNull
class java.lang.String
true
false
true
true

代码分析

net.sf.json.JSONObject本身就实现了Map接口:

public final class JSONObject extends AbstractJSON 
    implements JSON, Map, Comparable {
    ...
}

其内部维护了一个Map属性,实际就是一个HashMap:

// 成员变量
private Map properties;

// 构造方法
public JSONObject() {
    this.properties = new ListOrderedMap();
}

public ListOrderedMap() {
    this(new HashMap());
}

注意:

  • 非”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);
        }
    }
}

这就是为什么:

System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull

System.out.println(jsonObject.get("key2").getClass());//class java.lang.String

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"));

键为 “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);
    }

所以:

System.out.println(itemsMap.get("key").equals("null"));//true

“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")));

此时”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;
    }

执行分析:

  • 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
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值