對於剛接觸不久面向對象的真小白童鞋來講,類的對象,對象的實例,對象的引用,引用變量的問題以及莫過於沒得對象~雖然博主也沒得對象~,本文將逐個逐個講解!javascript
在Java中有一句比較流行的話,叫作「萬物皆對象」,這是Java語言設計之初的理念之一。要理解什麼是對象,須要跟類一塊兒結合起來理解。下面這段話引自《Java編程思想》中的一段原話: java
「按照通俗的說法,每一個對象都是某個類(class)的一個實例(instance),這裏,‘類’就是‘類型’的同義詞。」程序員
從這一句話就能夠理解到對象的本質,簡而言之,它就是類的實例,好比全部的人統稱爲「人類」,這裏的「人類」就是一個類(物種的一種類型),而具體到每一個人,好比張三這我的,它就是對象,就是「人類」的實例。 編程
咱們先看一段話,這段話一樣來自於《Java編程思想》: 編程語言
「每種編程語言都有本身的數據處理方式。有些時候,程序員必須注意將要處理的數據是什麼類型。你是直接操縱元素,仍是用某種基於特殊語法的間接表示(例如C/C++裏的指針)來操做對象。全部這些在 Java 裏都獲得了簡化,一切都被視爲對象。所以,咱們可採用一種統一的語法。儘管將一切都「看做」對象,但操縱的標識符實際是指向一個對象的「引用」(reference)。」ui
很顯然,從這段話能夠看出對象和對象引用不是一回事,是兩個徹底不一樣的概念。舉個例子,咱們一般會用下面這一行代碼來建立一個對象:編碼
 Person per = new Person("張三");
複製代碼
有小白童鞋會說,這裏的per
是一個對象,是Person
類的一個實例。也有小白童鞋會說,這裏的per
並非真正的對象,而是指向所建立的對象的引用。到底哪一種說法是對的?咱們先不急着糾結哪一種說法是對的,再看兩行代碼: spa
 Person person;
person = new Person("張三");
複製代碼
這兩行代碼實現的功能和上面的一行代碼是徹底同樣的。你們都知道,在Java中new
是用來在堆上建立對象用的,若是per
是一個對象的話,那麼第二行爲什麼還要經過new
來建立對象呢?設計
因而可知,per
並非所建立的對象,是什麼?上面的一段話說的很清楚,「操縱的標識符實際是指向一個對象的引用」,也就是說per
是一個引用,是指向一個能夠指向Person
類的對象的引用。真正建立對象的語句是右邊的new Person("張三")
;所以這裏的per
是一個引用,是指向一個能夠指向Person
類的對象的引用。指針
簡單來講,對象的引用意思是「定義一個變量,這個變量指向的是一個對象「
Object obj=new Object();
//Object:類
//obj:對象的引用
//new Object():對象
複製代碼
首先,沒有「對象的實例」這一說法,只有類的實例,而類的實例,指的就是類的對象,說白了就是對象。 可是仍是有不少人這樣叫,那怎麼理解對象實例呢?好比說人類中有個叫宜春的程序員,宜春就是人類的一個實例
String s = new String("YiChun");
複製代碼
s
就是 String
類中的一個實例
關於對象實例官方沒有給其概念,其實有不少概念官方都沒有給的,什麼父類聲明指向子類對象、方法簽名等概念都是沒有的 ,只是人們常常這麼用這麼說就習慣了。所以關於實例對象大致能夠理解爲對象引用的意思...
引用變量就是用引用類型聲明的變量,這種變量叫引用類型變量。如:
People people; //其中people就是引用變量,People是一個類屬於引用類型
複製代碼
從對象引用出發:
一個對象引用能夠指向零個或一個對象
從對象出發:
一個對象能夠被一個或多個對象引用
怎麼理解捏?~小白童鞋腦袋逐漸變大...~
首先先來理解第一句話:從對象引用出發:一個對象引用能夠指向零個或一個對象
public static void main(String[] args) {
Two t; //一個對象引用能夠指向零個對象
t=new Two();//一個對象引用能夠指向一個對象
t=new String();//一個對象引用不能夠指向 >1個對象
}
複製代碼
試想一下這樣的代碼會出現啥狀況?是的,它會編譯失敗
看完上面這個例子就能說明了麼?咱們接着看下面這個代碼:public static void main(String[] args) {
String str;
str=new String("string1");
str=new String("string2");
}
複製代碼
咱們知道,凡是new
都能建立出一個對象,咱們發現上面代碼String
對象引用str
一個new
了兩次,並且上面代碼編譯也不報錯,的的確確是建立了兩個對象,那這怎麼說?小白童鞋說完感受把博主按在馬桶蓋上...
別急,咱們再看看上面代碼輸出啥
public static void main(String[] args) {
String str;
str=new String("string1");
str=new String("string2");
System.out.println(str);
}
運行結果: string2
複製代碼
這說明啥?說明如今str是下一個對象的引用。上一個對象被垃圾回收了,由於上一個對象(也就是string1
)不能被再次使用了。所以上面這個程序能夠這樣理解:
public static void main(String[] args) {
String str;//一個對象引用str指向零個對象
str=new String("string1");//一個對象引用str指向一個對象string1
str=new String("string2");//注意:這裏對象引用str並非指向第二個對象string2,而是將以前指向第一個對象string1的引用從新指向了另外一個對象string2
}
複製代碼
對象引用str並非指向第二個對象string2,而是將以前指向第一個對象string1的引用從新指向了另外一個對象string2,所以從對象引用出發:一個對象引用能夠指向零個或一個對象!
這個時候,小白童鞋漸漸鬆開了把博主按在馬桶蓋上的雙手...
咱們再來理解一下第二句話:從對象出發,一個對象能夠被一個或多個對象引用
小白童鞋一樣不解,因而又用雙手把博主按在馬桶蓋上...
看下面這個程序:
Demo demo1,demo2,demo3;
demo1=new Demo();
demo2=demo1;
demo3=demo2;
複製代碼
怎麼理解?看的有點暈?會不會感受後面兩句代碼就是對象引用=對象引用...
其實要弄清除這個,首先你得弄清楚java虛擬機內存,弄清楚變量(對象引用)和對象是如何存儲的,對象引用是存儲在棧內存中,而對象是存儲在堆內存中。分析以下:
Demo demo1,demo2,demo3;//建立多個對象引用,都存儲在棧中
demo1=new Demo();//建立一個Demo對象,存儲在堆中,並將demo1指向這個對象,至關於加了一個鏈
demo2=demo1;//demo2與demo1同樣,都指向堆中Demo對象
demo3=demo2;//demo3與demo2同樣,都指向堆中Demo對象
複製代碼
首先,每一個對象只有一個地址值,new Demo()
是建立了一個對象,demo1
是這個對象的地址值,用來找到這個對象,demo2=demo1
是把new Demo()
這個對象的地址值由demo1
改成了demo2
,後面的demo3=demo2
也是隻改變了對象的地址值,對象自己的空間大小都沒有變化,變的,是這個對象的地址值,也就是c裏面所謂的指針。
這個時候,小白童鞋漸漸鬆開了把博主按在馬桶蓋上的雙手...
最後,咱們再看看一個網上關於對象與對象引用很流行的程序與分析,代碼以下:
UserType ut = new UserType(); // ut是引用,實際的對象在內存裏。
ut = new UserType(); /*如今ut是另外一個對象的引用,先前的對象被垃圾回收了(由於先前的對象不能被再次使用了)。*/
UserType ut2; // 定義了一個引用ut2,他不引用任何對象,不能使用。。。。
ut2 = new UserType(); // 然ut2成爲一個對象的引用。
UserType ut3 = new UserType();
UserType ut4 = new UserType();
ut3 = ut4; // 如今ut3引用ut4的對象,這裏不是賦值。。。
int a = 5;
int b = 4;
a = b; // 這裏是賦值。 a b 依然引用不一樣的對象
複製代碼
對於面嚮對象語言,如java,首先,請小白童鞋相信一句話:一切皆爲對象。而後相信另外一句話:變量只是一個零時的儲存地點。引用類型的變量只是一個普通變量,儲存了引用類型的地址。對象的建立是直接在內存中分配一個內存。
最後再梳理一下
引用類型變量 就 至關於 電腦上的快捷方式; 對象就至關於 你 磁盤裏面 安裝的遊戲,它 實實在在 佔用你的空間內存; 而變量 只是快捷方式
說白了基本數據類型變量就像是直接放在櫃子裏的東西,而引用數據類型變量就是這個櫃子對應編碼的鑰匙。鑰匙號和櫃子對應。
到這裏文章就結束了喔,小白童鞋,你何識着咩啊~
最後,如有不足或者不正之處,歡迎指正批評,感激涕零!
歡迎各位關注個人公衆號,一塊兒探討技術,嚮往技術,追求技術...
小白童鞋關注了個人公衆號以後,又用雙手把博主按在馬桶蓋蓋上....