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


    之前遇到一些关于两个引用类型是否指向同一个对象的问题,如下定义的(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)就不是同一个东西了。

  • 相关阅读:
    Grunt jshint Warning: Path must be a string . Received null Use
    bootstrap滚动监视原理实现
    Bootstrap模态框原理分析及问题解决
    LeetCode54. 螺旋矩阵
    LeetCode53. 最大子序和
    mysql servers实现层拼写SQL
    easyUI 分页 获取页面
    excel导入功能
    easyUI遮罩
    uuid生成
  • 原文地址:https://www.cnblogs.com/Yuzao/p/14755781.html
Copyright © 2020-2023  润新知