Hello,今天我们来学习Java的引用概念。 先回顾一下昨天的代码。
代码语言:javascript复制class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
System.out.println("程序启动了...");
}
}
其中有一句:
代码语言:javascript复制System.out.println("程序启动了...");
程序启动了...
这几个字是用双引号括起来的,在Java中,用双引号括起来的部分叫做字符串,顾名思义,就是若干个字符组成的串串,叫做字符串。
当我们写"程序启动了..."
的时候,就会开辟一块内存空间,保存这些数据。
字符串是一个对象,在java中,对象是存放在堆
中的。也就是说,"程序启动了..."
是存放在堆中的。
堆是Java用来存储对象数据的地方,我们直接写"程序启动了..."
的时候,就会创建一个字符串对象。存放到Java堆中。
堆
可以把堆理解为一家餐厅,里面有200张桌子,也就是最多能同时容纳200桌客人就餐,来一批客人就为他们安排一些桌子,如果某天来的客人特别多,超过200桌了,那就不能再接待超出的客人了。
当然,进来吃饭的客人不可能是同时的,有的早,有的晚,先吃好的客人,老板会安排给他们结账走人,然后空出来的桌子又能接待新的客人。
这里,堆就是餐厅,最大容量200桌就是堆内存的大小,老板就相当于GC(垃圾回收),给客人安排桌子就相当于java创建对象的时候分配堆内存,结账就相当于GC回收对象占用的空间。
有了这个初步认识,再来看官方的介绍:对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java 世界里“几乎”所有的对象实例都在这里分配内存。
是不是就好理解多了呢?
我们需要一个引用
在之前的例子中,我们写"程序启动了..."
的目的是得到一个字符串对象,但是这种写法是昙花一现的,只在
System.out.println("程序启动了...");
这行代码中一次生效,如果我们需要多次使用这个字符串,就没有办法。
没有办法就是没有办法,即便你写:
代码语言:javascript复制System.out.println("程序启动了...");
System.out.println("程序启动了...");
也是两个不同的字符串,不是多次使用同一个字符串的概念。
为了解决这个问题,我们需要一个引用。
什么是引用呢?如果java对象是一个电视机,那么引用就是遥控器,你只要有遥控器,就可以控制电视机开机关机,播放你想要看的节目。你拿着遥控器,相当于有了电视机。
而刚才的代码
代码语言:javascript复制System.out.println("程序启动了...");
相当于你抱着电视机,而不是拿起遥控器。
Java的引用,是需要和对象绑定起来讲的,比如我们可以这样写:
代码语言:javascript复制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
也可以叫做对象的引用
,因为它拥有了操控对象的权力。
好了,本节的目标就是把字符串赋值给引用。
代码语言:javascript复制class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
String s = "程序启动了...";
System.out.println(s);
}
}
ctrl 1 编译
ctrl 2 运行