对象引用与对象存放的地址和区别

本文深入探讨了Java中对象与引用的区别,通过实例详细解释了对象的创建过程,包括对象的初始化、引用变量的创建以及指针操作。并通过单链表和双链表的示例,进一步阐述了引用修改对对象的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在java的学习当中,很多时候并没有能很好分清把对象和对象的引用。如果没能很好认识分清这两者的关系,就可能会很难理解一些指针的移动的代码。

JAVA基本类型的变量的时其变量名及值(变量名及值是两个概念)是放在方法栈中,引用类型所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在方法的栈中,该变量所指向的对象是放在堆类存中的。

我们先定义一个简单的类:

public class DemoClass {
    private String name;
}

有了这个模板,就可以用它来创建对象:
DemoClass demo= new DemoClass ();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
1)右边的“ new DemoClass”,是以DemoClass类为模板,在堆空间里创建一个DemoClass类对象(也简称为DemoClass对象)。
2)末尾的()意味着,在对象创建后,立即调用DemoClass类的构造函数,对刚生成的对象进行初始化。
3)左边的“DemoClass”创建了一个DemoClass类引用变量。所谓DemoClass类引用,就是以后可以用来指向DemoClass对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个DemoClass对象。
我们可以把这条语句拆成两部分:
DemoClass demo; --对象引用变量
demo= new DemoClass (); --对象本身
效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。

通过上面知识我们来看两个相对复杂一点demo,这个例子中通过tempHead 改变对实体对象指向的改变,使其tempHead 一直指向链表的末尾。head 指向链表头部

public class TempClass {

    @Test
   public void replaceSingleNode(){
        //定义一个请求头对象
       SingleLinkedNode head = new SingleLinkedNode(0);
       //定义tempHead的引用名 将指向  new SingleLinkedNode(0) 这个对象本身
       SingleLinkedNode tempHead=head;
       for (int i = 1; i <=5 ; i++) {
           //tempHead.next 引用名  将指向 new SingleLinkedNode(i)本身
           tempHead.next = new SingleLinkedNode(i);
           //tempHead引用名  指向  tempHead 的下个对象本身
           tempHead = tempHead.next;
       }
       //这个时候head 这个引用名 实际指向  new SingleLinkedNode(0);
       System.out.println("请求头:"+head);
       //这个时候 tempHead 这个应用名实际指向  new SingleLinkedNode(i); 当i=5的时候
       System.out.println("运输对象:"+tempHead);
   }


    @Data
    class SingleLinkedNode{
        private int value;
        private SingleLinkedNode next;

        public SingleLinkedNode(int value) {
            this.value = value;
        }

    }





}

打印内容

请求头:TempClass.SingleLinkedNode(value=0, next=TempClass.SingleLinkedNode(value=1, next=TempClass.SingleLinkedNode(value=2, next=TempClass.SingleLinkedNode(value=3, next=TempClass.SingleLinkedNode(value=4, next=TempClass.SingleLinkedNode(value=5, next=null))))))
运输对象:TempClass.SingleLinkedNode(value=5, next=null)

我们的出 tempHead = tempHead.next; 只是改变tempHead 这个引用对象,而不是直接对对象进行替换,我这里再用一个双链表来作证这一结论。在双链表中如果是不是覆盖,那最后tempHead就应该保留整条链表数据,只是tempHead指向链表末尾的字段。

public class TempClass {

    
    @Test
    public void replaceDoubleNode(){
        //定义一个请求头对象
        DoubleLinkedNode head = new DoubleLinkedNode(0);
        //定义tempHead的引用名 将指向  new SingleLinkedNode(0) 这个对象本身
        DoubleLinkedNode tempHead=head;
        for (int i = 1; i <=5 ; i++) {
            //newNode 引用名  将指向 new SingleLinkedNode(i)实体本身
            DoubleLinkedNode newNode = new DoubleLinkedNode(i);
            //tempHead.tail 这个引用 指向new DoubleLinkedNode(i);实体
            tempHead.tail =newNode;
            //newNode 这个引用 指向tempHead 的实体
            newNode.front = tempHead;
            //将tempHead 指向  tempHead.tail 实体 ,也就是 new DoubleLinkedNode(i) 实体本身
            tempHead = tempHead.tail;
        }
        System.out.println("请求头:"+head);
        System.out.println("运输对象:"+tempHead);
    }







    class DoubleLinkedNode{
        private int value;
        private DoubleLinkedNode front;
        private DoubleLinkedNode tail;

        public DoubleLinkedNode(int value) {
            this.value = value;
        }
    }
}

在这里插入图片描述

希望通过这里讲解说明,能够很好的认识引用和对象本身的区别

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值