ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

关于JAVA的引用(地址)的一些理解

2021-05-11 16:04:10  阅读:157  来源: 互联网

标签:JAVA jsonObject System value 地址 引用 JSONObject new data


之前遇到一些关于两个引用类型是否指向同一个对象的问题,如下定义的\(ResponseObject\)中的,在这个类中,先将 \(data\) 从 \(jsonObject\) 中取出,随后所有的操作都从 \(data\) 中进行操作。
之前一直以为 \(jsonObject\) 中的 \(data\) 无论如何都是会跟着外面的 \(data\) 一起发生变化的,实际上并不一定。

class ResponseObject {
    public JSONObject data;
    private JSONObject jsonObject;
    ResponseObject(JSONObject jsonObject) {
        this.data = jsonObject.getJSONObject("data");
        this.jsonObject = jsonObject;
    }

    public void put(String key, Object value) {
        if (data == null) {
            data = new JSONObject();
            this.jsonObject.put("data", data);
        }
        data.put(key, value);
    }
    public JSONObject getData() {
        return this.jsonObject.getJSONObject("data");
    }
}

按道理来说, \(jsonObject\) 中的 \(data\) 和外面的 \(data\) 指向的是同一个对象,也就是说他们的地址是相同的。
进行测试

public class Test {
    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        JSONObject data = new JSONObject();
        jsonObject.put("data", data);

        ResponseObject t = new ResponseObject(jsonObject);

        JSONObject bearObj = new JSONObject();
        t.put("bear",  bearObj);

        System.out.println(System.identityHashCode(t.getData()));
        System.out.println(System.identityHashCode(t.data)); //不能仅用hashCode()来判断,若复写了hashCode()则输出的就不是地址。

    }
}

上面的输出为:

{"bear":{}}
{"bear":{}}
83954662
83954662

确实和期望一样,插入元素之后两者都发生了变化,且地址也是一样的,可见他们是指向相同的对象的。
但我们做以下的更改:

public class Test {
    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
        Map<String, Object> data = new HashMap<String, Object>();
        jsonObject.put("data", data);

        ResponseObject t = new ResponseObject(jsonObject);

        JSONObject bearObj = new JSONObject();
        t.put("bear",  bearObj);

        System.out.println(t.getData());
        System.out.println(t.data);
        System.out.println(System.identityHashCode(t.getData()));
        System.out.println(System.identityHashCode(t.data));

    }
}

发现输出和期望的就有所不同了:

{}
{"bear":{}}
777874839
1751075886

原因很简单,通过观察 \(com.alibaba.fastjson.JSONObject\) 的代码

public JSONObject getJSONObject(String key) {
        Object value = map.get(key);

        if (value instanceof JSONObject) {
            return (JSONObject) value;
        }

        if (value instanceof String) {
            return JSON.parseObject((String) value);
        }

        return (JSONObject) toJSON(value);
    }

发现这个方法在 \(data\) 不是 \(JSONObject\) 类时,会新建一个 \(JSONObject\) 然后再将元素插入进去,因此地址会发生改变,这种时候\(ResponseObject\)中的\(data\)与\(jsonObject\)中的\(data\)就不是同一个东西了。

标签:JAVA,jsonObject,System,value,地址,引用,JSONObject,new,data
来源: https://www.cnblogs.com/Yuzao/p/14755781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有