目录

​​堆​​

​​我们需要一个引用​​

Hello,今天我们来学习Java的引用概念。 先回顾一下昨天的代码。

class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
System.out.println("程序启动了...");
}
}

其实有一句:

System.out.println("程序启动了...");

​程序启动了... ​​这几个字是用双引号括起来的,在Java中,用双引号括起来的部分叫做字符串,顾名思义,就是若干个字符组成的串串,叫做字符串。

当我们写​​"程序启动了..."​​的时候,就会开辟一块内存空间,保存这些数据。

字符串是一个对象,在java中,对象是存放在​​堆​​​中的。也就是说,​​"程序启动了..."​​是存放在堆中的。

堆是Java用来存储对象数据的地方,我们直接写​​"程序启动了..."​​的时候,就会创建一个字符串对象。存放到Java堆中。

可以把堆理解为一家餐厅,里面有200张桌子,也就是最多能同时容纳200桌客人就餐,来一批客人就为他们安排一些桌子,如果某天来的客人特别多,超过200桌了,那就不能再接待超出的客人了。

当然,进来吃饭的客人不可能是同时的,有的早,有的晚,先吃好的客人,老板会安排给他们结账走人,然后空出来的桌子又能接待新的客人。

这里,堆就是餐厅,最大容量200桌就是堆内存的大小,老板就相当于GC(垃圾回收),给客人安排桌子就相当于java创建对象的时候分配堆内存,结账就相当于GC回收对象占用的空间。

有了这个初步认识,再来看官方的介绍:对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。

是不是就好理解多了呢?

我们需要一个引用

在之前的例子中,我们写​​"程序启动了..."​​的目的是得到一个字符串对象,但是这种写法是昙花一现的,只在

System.out.println("程序启动了...");

这行代码中一次生效,如果我们需要多次使用这个字符串,就没有办法。

没有办法就是没有办法,即便你写:

System.out.println("程序启动了...");
System.out.println("程序启动了...");

也是两个不同的字符串,不是多次使用同一个字符串的概念。

为了解决这个问题,我们需要一个引用。

什么是引用呢?如果java对象是一个电视机,那么引用就是遥控器,你只要有遥控器,就可以控制电视机开机关机,播放你想要看的节目。你拿着遥控器,相当于有了电视机。

而刚才的代码

System.out.println("程序启动了...");

相当于你抱着电视机,而不是拿起遥控器。

Java的引用,是需要和对象绑定起来讲的,比如我们可以这样写:

String s = "程序启动了...";

​String​​​是Java的一种类型class,​​s​​​是变量名,当​​s​​​等于一个具体的对象​​"程序启动了..."​​​的时候,​​s​​​就成为了一个​​引用​​。

为什么呢,因为当运行到​​"程序启动了..."​​​的时候,java会在堆中创建一个对象,堆是一块内存空间,参考上面的比喻就是桌子,桌子有编号,比如88号。所以​​String s = "程序启动了...";​​​的意思就是我们把88号桌子分配给变量​​s​​​,从此变量​​s​​​就代表字符串对象​​"程序启动了..."​​。

好了,下面有请两位杠精朋友登场。

杠精A:明白了,那我写​​String s;​​的时候,就是定义了引用s对吧?

答:谁跟你讲的?你直接写​​String s;​​,却没有对象赋值给它,它就不叫引用。它... ...它.. ....只是一个变量而已!(咋还急眼了)

杠精B:按照你的说法,如果我知道了内存中的地址,是不是直接赋值给它就行了,比如我写​​String s = 88;​​,也能指向那个字符串对象吧?

答:首先,88是一个数字,无法赋值给String类型的s。其次,这么理解是不对的,因为就算内存地址真的是88,直接写个内存地址也不能起到引用的效果啊,它就是个数字而已。(话说你这想法挺新奇的??)

​"程序启动了..."​​​这个对象创建后的返回值是一个​​引用​​​,而​​s​​​是一个变量,我们把一个​​引用​​​赋值给变量​​s​​​。那么,变量​​s​​​也可以叫做对象的​​引用​​,因为它拥有了操控对象的权力。

好了,本节的目标就是把字符串赋值给引用。

class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
String s = "程序启动了...";
System.out.println(s);
}
}

ctrl+1 编译

ctrl+2 运行

JavaSE成神之路 - 我创建一个引用后赋值对象(必看)_java