zoukankan      html  css  js  c++  java
  • 关于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)就不是同一个东西了。

  • 相关阅读:
    软件实施工程师是一个什么样的工作?他的具体工作内容是什么?发展前景怎样?
    做金融(基金、证券)方面的软件实施工程师有没有发展前途?职业发展空间如何。
    做软件实施工程师的一点建议
    系统实施工程师主要工作职则
    软件实施工程师
    UE编辑器编译和运行java设置
    猜数字
    猜数字
    Problem G
    Problem G
  • 原文地址:https://www.cnblogs.com/Yuzao/p/14755781.html
Copyright © 2011-2022 走看看