Hello,今天我們來學習Java的引用概念。
先回顧一下昨天的代碼。
class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
System.out.println("程序啟動了...");
}
}
其中有一句:
System.out.println("程序啟動了...");
程序啟動了...這幾個字是用雙引號括起來的,在Java中,用雙引號括起來的部分叫做字符串,顧名思義,就是若干個字符組成的串串,叫做字符串。
當我們寫"程序啟動了..."的時候,就會開辟一塊內存空間,保存這些數(shù)據(jù)。
字符串是一個對象,在java中,對象是存放在堆中的。也就是說,"程序啟動了..."是存放在堆中的。
堆是Java用來存儲對象數(shù)據(jù)的地方,我們直接寫"程序啟動了..."的時候,就會創(chuàng)建一個字符串對象。存放到Java堆中。
堆
可以把堆理解為一家餐廳,里面有200張桌子,也就是最多能同時容納200桌客人就餐,來一批客人就為他們安排一些桌子,如果某天來的客人特別多,超過200桌了,那就不能再接待超出的客人了。
當然,進來吃飯的客人不可能是同時的,有的早,有的晚,先吃好的客人,老板會安排給他們結賬走人,然后空出來的桌子又能接待新的客人。
這里,堆就是餐廳,最大容量200桌就是堆內存的大小,老板就相當于GC(垃圾回收),給客人安排桌子就相當于java創(chuàng)建對象的時候分配堆內存,結賬就相當于GC回收對象占用的空間。
有了這個初步認識,再來看官方的介紹:對于Java應用程序來說,Java堆(Java Heap)是虛擬機所管理的內存中最大的一塊。Java堆是被所有線程共享的一塊內存區(qū)域,在虛擬機啟動時創(chuàng)建。此內存區(qū)域的唯一目的就是存放對象實例,Java 世界里“幾乎”所有的對象實例都在這里分配內存。
是不是就好理解多了呢?
我們需要一個引用
在之前的例子中,我們寫"程序啟動了..."的目的是得到一個字符串對象,但是這種寫法是曇花一現(xiàn)的,只在
System.out.println("程序啟動了...");
這行代碼中一次生效,如果我們需要多次使用這個字符串,就沒有辦法。
沒有辦法就是沒有辦法,即便你寫:
System.out.println("程序啟動了...");
System.out.println("程序啟動了...");
也是兩個不同的字符串,不是多次使用同一個字符串的概念。
為了解決這個問題,我們需要一個引用。
什么是引用呢?如果java對象是一個電視機,那么引用就是遙控器,你只要有遙控器,就可以控制電視機開機關機,播放你想要看的節(jié)目。你拿著遙控器,相當于有了電視機。
而剛才的代碼
System.out.println("程序啟動了...");
相當于你抱著電視機,而不是拿起遙控器。
Java的引用,是需要和對象綁定起來講的,比如我們可以這樣寫:
String s = "程序啟動了...";
String是Java的一種類型class,s是變量名,當s等于一個具體的對象"程序啟動了..."的時候,s就成為了一個引用。
為什么呢,因為當運行到"程序啟動了..."的時候,java會在堆中創(chuàng)建一個對象,堆是一塊內存空間,參考上面的比喻就是桌子,桌子有編號,比如88號。所以String s = "程序啟動了...";的意思就是我們把88號桌子分配給變量s,從此變量s就代表字符串對象"程序啟動了..."。
好了,下面有請兩位杠精朋友登場。
杠精A:明白了,那我寫String s;的時候,就是定義了引用s對吧?
答:誰跟你講的?你直接寫String s;,卻沒有對象賦值給它,它就不叫引用。它... ...它.. ....只是一個變量而已?。ㄕ€急眼了)
杠精B:按照你的說法,如果我知道了內存中的地址,是不是直接賦值給它就行了,比如我寫String s = 88;,也能指向那個字符串對象吧?
答:首先,88是一個數(shù)字,無法賦值給String類型的s。其次,這么理解是不對的,因為就算內存地址真的是88,直接寫個內存地址也不能起到引用的效果啊,它就是個數(shù)字而已。(話說你這想法挺新奇的??)
"程序啟動了..."這個對象創(chuàng)建后的返回值是一個引用,而s是一個變量,我們把一個引用賦值給變量s。那么,變量s也可以叫做對象的引用,因為它擁有了操控對象的權力。
好了,本節(jié)的目標就是把字符串賦值給引用。
class Customer {}
class Vip {}
public class Demo {
public static void main(String[] args){
String s = "程序啟動了...";
System.out.println(s);
}
}
ctrl+1 編譯
ctrl+2 運行
