解惑真小白的苦惱 | 類的對象,對象引用,對象實例,引用變量


對於剛接觸不久面向對象的真小白童鞋來說,類的對象,對象的實例,對象的引用,引用變量的問題以及莫過於沒得對象雖然博主也沒得對象,本文將逐個逐個講解!

1.何謂對象?

  在Java中有一句比較流行的話,叫做“萬物皆對象”,這是Java語言設計之初的理念之一。要理解什么是對象,需要跟類一起結合起來理解。下面這段話引自《Java編程思想》中的一段原話:
  

“按照通俗的說法,每個對象都是某個類(class)的一個實例(instance),這里,‘類’就是‘類型’的同義詞。”

  從這一句話就可以理解到對象的本質,簡而言之,它就是類的實例,比如所有的人統稱為“人類”,這里的“人類”就是一個類(物種的一種類型),而具體到每個人,比如張三這個人,它就是對象,就是“人類”的實例。
  

2.何謂對象引用?

我們先看一段話,這段話同樣來自於《Java編程思想》:
 

 “每種編程語言都有自己的數據處理方式。有些時候,程序員必須注意將要處理的數據是什么類型。你是直接操縱元素,還是用某種基於特殊語法的間接表示(例如C/C++里的指針)來操作對象。所有這些在
Java
里都得到了簡化,一切都被視為對象。因此,我們可采用一種統一的語法。盡管將一切都“看作”對象,但操縱的標識符實際是指向一個對象的“引用”(reference)。”

  很顯然,從這段話可以看出對象和對象引用不是一回事,是兩個完全不同的概念。舉個例子,我們通常會用下面這一行代碼來創建一個對象:

 

 Person per = new Person("張三");

有小白童鞋會說,這里的per是一個對象,是Person類的一個實例。也有小白童鞋會說,這里的per並不是真正的對象,而是指向所創建的對象的引用。到底哪種說法是對的?我們先不急着糾結哪種說法是對的,再看兩行代碼:
 

 Person person;
  person = new Person("張三");

  這兩行代碼實現的功能和上面的一行代碼是完全一樣的。大家都知道,在Java中new是用來在堆上創建對象用的,如果per是一個對象的話,那么第二行為何還要通過new來創建對象呢?

由此可見,per並不是所創建的對象,是什么?上面的一段話說的很清楚,“操縱的標識符實際是指向一個對象的引用”,也就是說per是一個引用,是指向一個可以指向Person類的對象的引用。真正創建對象的語句是右邊的new Person("張三");因此這里的per是一個引用,是指向一個可以指向Person類的對象的引用。

簡單來說,對象的引用意思是定義一個變量,這個變量指向的是一個對象

Object  obj=new Object();
//Object:類
//obj:對象的引用
//new Object():對象

3.何謂對象實例?

首先,沒有“對象的實例”這一說法,只有類的實例,而類的實例,指的就是類的對象,說白了就是對象。
但是還是有很多人這樣叫,那怎么理解對象實例呢?比如說人類中有個叫宜春的程序員,宜春就是人類的一個實例

String s = new String("YiChun");

s 就是 String類中的一個實例

關於對象實例官方沒有給其概念,其實有很多概念官方都沒有給的,什么父類聲明指向子類對象、方法簽名等概念都是沒有的 ,只是人們經常這么用這么說就習慣了。因此關於實例對象大體可以理解為對象引用的意思...

4.何謂引用變量?

引用變量就是用引用類型聲明的變量,這種變量叫引用類型變量。如:

People people;  //其中people就是引用變量,People是一個類屬於引用類型

5、對象與對象引用碰撞火花

從對象引用出發:

一個對象引用可以指向零個或一個對象

從對象出發:

一個對象可以被一個或多個對象引用

怎么理解捏?小白童鞋腦殼逐漸變大...

5、1. 從對象引用出發:一個對象引用可以指向零個或一個對象

首先先來理解第一句話:從對象引用出發:一個對象引用可以指向零個或一個對象

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,因此從對象引用出發:一個對象引用可以指向零個或一個對象!

這個時候,小白童鞋漸漸松開了把博主按在馬桶蓋上的雙手...

5、2. 從對象出發:一個對象可以被一個或多個對象引用

我們再來理解一下第二句話:從對象出發,一個對象可以被一個或多個對象引用

小白童鞋同樣不解,於是又用雙手把博主按在馬桶蓋上...

看下面這個程序:

   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 依然引用不同的對象

6、最后要相信的真理

對於面向對象語言,如java,首先,請小白童鞋相信一句話:一切皆為對象。然后相信另一句話:變量只是一個零時的儲存地點。引用類型的變量只是一個普通變量,儲存了引用類型的地址。對象的創建是直接在內存中分配一個內存。

最后再梳理一下

引用類型變量 就 相當於 電腦上的快捷方式; 對象就相當於 你 磁盤里面 安裝的游戲,它 實實在在 占用你的空間內存; 而變量 只是快捷方式

說白了基本數據類型變量就像是直接放在櫃子里的東西,而引用數據類型變量就是這個櫃子對應編碼的鑰匙。鑰匙號和櫃子對應。

到這里文章就結束了喔,小白童鞋,你何識着咩啊~

最后,若有不足或者不正之處,歡迎指正批評,感激不盡!

歡迎各位關注我的公眾號,一起探討技術,向往技術,追求技術...

在這里插入圖片描述
小白童鞋關注了我的公眾號之后,又用雙手把博主按在馬桶蓋蓋上....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM