vlambda博客
学习文章列表

Java—对象与对象引用的区别及浅谈栈、堆空间

一、前言

  在学习java语言中,最重要的肯定是对对象的理解认知。其实,在很多时候我常常会将对象的一些知识混淆,借此机会来自我总结一下。

  首先我将 栈 和 堆 两个储存机制简单的梳理一下,并在下面会为大家进行深入的讨论。

 

栈:声明对象引用的时候 会储存在栈 (储存基本数据类型)

堆:当我们new一个新对象时 会储存在堆

 

二、分析对象和对象引用的区别

首先我们先建立一个新的类,方便我们后面的分析

 


接下来我们在这个Student类下面创建一个对象

 Java—对象与对象引用的区别及浅谈栈、堆空间


  在这句简单的Student student= new Student(); 中 其实蕴含了四个意义

1)右边的“new Student”,是以Student类为模板,在堆空间里创建一个Student对象。

2)末尾的()意味着,在对象创建后,立即调用Student类的构造函数,对刚生成的对象进行初始化。

3)左边的“Student student”创建了一个Student类引用变量,它存放在栈空间中。也就是用来指向Student对象的对象引用。

4)“=”操作符使对象引用指向刚创建的那个Student对象。

当然我们也可以写成

Java—对象与对象引用的区别及浅谈栈、堆空间

此时在栈与堆空间中他们分别做了什么?

Java—对象与对象引用的区别及浅谈栈、堆空间

三、对象引用和对象之间的关系

1)从对象引用出发:

一个对象引用可以指向一个对象

Java—对象与对象引用的区别及浅谈栈、堆空间

当然可以不指向对象

只需要创建对象引用就可以了如:Student student

2)从对象出发:

一个对象可以被一个对象引用引用

也可以被多个对象引用指向

五、关于栈和堆的理解

栈内存:在上面有说到栈内存一般与基本数据类型挂钩。在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配,当一段代码块中定义一个变量的时候,Java就会在栈内存中为这个变量分配内存空间,当超出变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立刻被另作他用。

Tips:根据作用域的不同,一般将变量分为不同的类型:类变量、局部变量、方法参数变量及异常处理参数变量。

 

引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。引用变量就相当于是为数组或对象起的一个名称。而数组或对象本身在堆内存中分配,即使程序运行到使用 new 运算符创建数组或对象的语句所在的代码块之外,数组或对象本身所占据的内存也不会被释放,数组或对象在没有引用变量指向它时,会变为垃圾,不能再被使用,但仍然占据内存空间不放,在随后一个不确定的时间被垃圾回收器收走(释放掉),这也是Java比较占内存的原因。

 

Tips:Java有一个特殊的引用型常量null,如果将一个引用变量赋值为null,则表示该引用变量不指向(引用)任何对象。

 

六、区分栈和堆

栈是先进后出,而堆是先进先出。

 

1.栈内存存储的是局部变量而堆内存存储的是实体;

2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

关于堆内存:b站上面左神有一期专门对堆进行了解释,如果有兴趣可以自行搜索!