zoukankan      html  css  js  c++  java
  • 【转载】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类型:
     1 //
     2 // Source code recreated from a .class file by IntelliJ IDEA
     3 // (powered by Fernflower decompiler)
     4 //
     5 
     6 package net.sf.json;
     7 
     8 import java.io.IOException;
     9 import java.io.Writer;
    10 
    11 public final class JSONNull implements JSON {
    12     private static JSONNull instance = new JSONNull();
    13 
    14     public static JSONNull getInstance() {
    15         return instance;
    16     }
    17 
    18     private JSONNull() {
    19     }
    20 
    21     public boolean equals(Object object) {
    22         return object == null || object == this || object == instance || object instanceof JSONObject && ((JSONObject)object).isNullObject() || "null".equals(object);
    23     }
    24 
    25     public int hashCode() {
    26         return 37 + "null".hashCode();
    27     }
    28 
    29     public boolean isArray() {
    30         return false;
    31     }
    32 
    33     public boolean isEmpty() {
    34         throw new JSONException("Object is null");
    35     }
    36 
    37     public int size() {
    38         throw new JSONException("Object is null");
    39     }
    40 
    41     public String toString() {
    42         return "null";
    43     }
    44 
    45     public String toString(int indentFactor) {
    46         return this.toString();
    47     }
    48 
    49     public String toString(int indentFactor, int indent) {
    50         StringBuffer sb = new StringBuffer();
    51 
    52         for(int i = 0; i < indent; ++i) {
    53             sb.append(' ');
    54         }
    55 
    56         sb.append(this.toString());
    57         return sb.toString();
    58     }
    59 
    60     public Writer write(Writer writer) {
    61         try {
    62             writer.write(this.toString());
    63             return writer;
    64         } catch (IOException var3) {
    65             throw new JSONException(var3);
    66         }
    67     }
    68 }

    这就是为什么:

    1 System.out.println(jsonObject.get("key").getClass());//class net.sf.json.JSONNull
    2 
    3 System.out.println(jsonObject.get("key2").getClass());//class java.lang.String

    itemsMap.get(“key”).equals(“null”)

    分析:

    1 JSONObject jsonObject = new JSONObject();
    2 
    3 jsonObject.put("key", "null");
    4 
    5 Map itemsMap = (Map) jsonObject;
    6 
    7 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”))

    分析:

    1 JSONObject jsonObject = new JSONObject();
    2 
    3 jsonObject.put("key", "null");
    4 
    5 Map itemsMap = (Map) jsonObject;
    6 
    7 System.out.println("null".equals(itemsMap.get("key")));

    此时”null”.equals(itemsMap.get(“key”))调用的equals是String类的equals方法:

     1     /**
     2     * String复写的equals方法
     3     */
     4     public boolean equals(Object anObject) {
     5 
     6         // 比较地址是否相同,两个应用指向同一个对象(同一个地址)
     7         if (this == anObject) {
     8             return true;
     9         }
    10 
    11         // 判断是否是String类
    12         if (anObject instanceof String) {
    13             String anotherString = (String)anObject;
    14             int n = value.length;
    15             if (n == anotherString.value.length) {
    16                 char v1[] = value;
    17                 char v2[] = anotherString.value;
    18                 int i = 0;
    19                 while (n-- != 0) {
    20                     if (v1[i] != v2[i])
    21                         return false;
    22                     i++;
    23                 }
    24                 return true;
    25             }
    26         }
    27 
    28         // 返回结果
    29         return false;
    30     }

    执行分析:

    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
    
    
    
    
    
    
  • 相关阅读:
    android开发 PopupWindow 设置充满屏幕
    android 设置半透明
    web farm 讨论引出
    xamarin studio And linq 查询方式分析
    MONO 使用重要提示
    一个MVC的在线编译工具
    MONO Jexus部署最佳体验
    Origami
    产品原型设计工具 Balsamiq Mockups(转)
    VSPM虚拟串口使用
  • 原文地址:https://www.cnblogs.com/lixiaoxu/p/12909114.html
Copyright © 2011-2022 走看看