Java中對象和引用的理解

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

偶然想起Java中對象和引用的基本概念,為了加深下對此的理解和認識,特地整理一下相關的知識點,通過具體實例從兩者的概念和區別兩方面去更形象的認識理解,再去記憶。
  • 1
  • 2

一、對象和引用的概念:?
在Java中萬物皆對象,比如我們定義一個簡單的動物類:

class Animal {String count;String weight;....
}
  • 1
  • 2
  • 3
  • 4
  • 5

有了這個Animal類之后,我們可以來創建一個Animal對象:

Animal an = new Animal();
  • 1

我們把編寫這個語句的動作就稱作創建一個對象,細化這個動作為:?
1. 右面的”new Animal”,是以Animal類為模板的,在堆空間里創建一個Animal對象;?
2. 末尾的”( )”代表著:在對象創建之后,立即調用Animal類的構造函數,對新生成的對象進行初始化。(如果沒構造函數,Java會有一個默認的構造函數的);?
3. 左面的”Animal an” 創建了一個Animal類引用變量。即以后可以用來指向Animal對象的對象引用;?
4. “=” 操作符使對象引用指向剛才創建的那個Animal對象。?
拆分開也就是:等同于

Animal an;
an = new Animal();
  • 1
  • 2

有兩個實體:一個是對象引用變量;一個是對象本身。?
在java中,都是通過引用來操縱對象的,這也是兩者的區別。

二、對象和引用的區別:?
1、關聯性:?
1). 當對象的引用變量指向對象時,兩者就互相聯系起來,改變引用的屬性,就會改變對象的屬性;?
2). 如果同一個對象被多個引用變量引用的話,則這些引用變量將共同影響這個對象本身;?
3). 在java中,都是通過引用來操縱對象的。

2、差異性:?
1). 一個對象可以被不同的引用變量來操縱,同時一個引用變量也可以指向不同的對象,但是同一時刻下只能指向一個對象。?
2). 從存儲空間上來看,對象和引用也是相互獨立的,對象一般存儲在堆中,而引用存儲在堆棧中(存儲速度而更快)。

對于引用變量的深層含義,未必在初學的時候就能深刻理解,?
所以理解好下面這兩句話的真正含義非常重要

Case cc=new Case();Case cc;
cc=new Case();
  • 1
  • 2
  • 3
  • 4
  • 5

1.先搞清楚什么是堆,什么是棧。?
Java開辟了兩類存儲區域,對比二者的特點

存儲區域存儲內容優點缺點回收
基本類型的變量和對象的引用變量存取速度比堆要快,僅次于寄存器,棧數據可以共享存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類型的變量當超過變量的作用域后,Java會自動釋放掉該變量,內存空間可以立即被另作他用
由new等指令創建的對象和數組可以動態地分配內存大小,生存期也不必事先告訴編譯器由于要在運行時動態分配內存,存取速度較慢由Java虛擬機的自動垃圾回收器來回收不再使用的數據

堆棧的存儲特點決定了其中存儲的數據類型。

注意,棧內存儲的除了基本類型的變量(String, int 這種類型的變量)還會存儲對象的引用變量。java中,引用變量實際上是一個指針,它指向的是堆內存中對象實例。

引用變量就相當于是為數組或對象起的一個名稱,以后就可以在程序中使用棧中的引用變量來訪問堆中的數組或對象。

2.給引用變量賦值

回過頭再來看代碼

實際上里面分解成了四個步驟。

Case cc; '''在棧內存里面開辟了空間給引用變量cc,這時cc=null'''
cc=new Case();
'''
1. new Case()在堆內存里面開辟了空間給Case類的對象,這個對象沒有名字
2. Case()隨即調用了Case類的構造函數
3. 把對象的地址在堆內存的地址給引用變量cc
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這樣我們就明確了:

  • Java中,這里的“=”并不是賦值的意思,而是把對象的地址傳遞給變量;
  • 對象創建出來,其實連名字都沒有,因此必須通過引用變量來對其進行操作。

為了形象地說明對象、引用及它們之間的關系,可以做一個或許不很妥當的比喻。對象好比是一只很大的氣球,大到我們抓不住它。引用變量是一根繩, 可以用來系汽球

緊接著就會問,引用變量是怎么傳遞的呢??
這就涉及到Java唯一的參數傳遞方式——按值傳遞

看下面一段代碼:

public class ObjectRef {'''基本類型的參數傳遞'''public static void testBasicType(int m) {System.out.println("m=" + m);//m=50m = 100;System.out.println("m=" + m);//m=100}'''參數為對象,不改變引用的值''''''s即sMain指向的對象執行了append方法,在原來的字符串上加了段“_add”'''public static void add(StringBuffer s) {s.append("_add");}'''參數為對象,改變引用的值 ''''''引用變量指向了一個新的對象,已經不是sMain指向的對象了'''public static void changeRef(StringBuffer s) {s = new StringBuffer("Java");}public static void main(String[] args) {int i = 50;testBasicType(i);System.out.println(i);'''i=50'''StringBuffer sMain = new StringBuffer("init");System.out.println("sMain=" + sMain.toString());'''sMain=init'''add(sMain);System.out.println("sMain=" + sMain.toString());'''sMain=init_add'''changeRef(sMain);System.out.println("sMain=" + sMain.toString());'''sMain=Java'''}
}

看這里,給人的感覺是傳遞過來的明明是對象的引用,為什么就是值得傳遞呢??
因為傳遞之前,被傳的就是個引用啊,我們所謂的“傳地址”,在傳之前,那可是一個實例,傳過來的是實例的地址。這里傳遞的值,從始至終就是個地址,sMain就是個地址,傳給s還是個地址。你們感受下:

'''參數為對象,不改變引用的值'''
'''s即sMain,指向的對象執行了append方法,在原來的字符串上加了段“_add”'''public static void add(StringBuffer s) {s.append("_add");}

以上輸出的結果會是“init_add”

而這里,s引用了一個新的對象,根本沒有進行參數的傳遞,它和之前的sMain沒有關系了。

'''參數為對象,改變引用的值 '''
'''引用變量指向了一個新的對象,已經不是sMain指向的對象了'''public static void changeRef(StringBuffer s) {s = new StringBuffer("Java");}

以上輸出的結果會是“Java”?
.?
.?
引用《Java編程思想》中的一段話:

倘若“將一個對象賦值給另一個對象”,實際是將“引用”從一個地方復制到另一個地方:

轉載于:https://my.oschina.net/architectliuyuanyuan/blog/1630113

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452504.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452504.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452504.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android怎樣封裝,如何封裝屬于自己的博客網站安卓APP 源碼家園

說實話我今天在寫這個文章的時候是我使用易語言(E4A\易安卓)的第一天,我也是易小白,但是的確可以用!我為什么寫這個文章呢?因為之前我也想封裝自己的網站,然后去網上找的在線封裝生成APP,果然能封裝好了&am…

程序員常犯的5個非技術性錯誤

一個好的軟件開發人員需要培養兩種技能:技術技能和非技術技能。不幸的是一些開發者只注重技術的部分,以致養成一些陋習,下面是最常犯的5個非技術性錯誤: 0. 缺乏自律 Jim Rohn曾經說過:自律是目標和成果之間的橋梁。我…

Redis進階實踐之二十 Redis的配置文件使用詳解

一、引言   寫完上一篇有關redis使用lua腳本的文章,就有意結束Redis這個系列的文章了,當然了,這里的結束只是我這個系列的結束,但是要學的東西還有很多。但是,好多天過去了,總是感覺好像還缺點什么…

web流程設計器 工作流的 整合視頻教程 activiti畫圖 SSM和獨立部署

本視頻為activiti工作流的web流程設計器整合視頻教程整合Acitiviti在線流程設計器(Activiti-Modeler 5.21.0 官方流程設計器)本視頻共講了兩種整合方式1. 流程設計器和其它工作流項目分開部署的方式2. 流程設計器和SSM框架項目整合在一起的方式視頻大小 1.13 GB ~【…

Diango博客--7.自動生成文章摘要

文章目錄0.思路引導1.方法一:覆寫 save 方法2.方法二:使用 truncatechars 模板過濾器0.思路引導 博客文章的模型有一個 excerpt 字段,這個字段用于存儲文章的摘要。 若在 django admin 后臺手動為文章輸入摘要,每次手動輸入摘要…

android 增加觸摸范圍,android seekBar 增加點擊和滑動范圍

seekBar的的范圍有限,有時候設計師要求高度為4dp,此時范圍太小,很難滑動成功。因此,我們需要在不改變 UI 的前提下,增加點擊和滑動范圍。直接上代碼:public class MainActivity extends AppCompatActivity …

特斯拉股價暴跌,瘋狂燒錢是否真的能夠帶來高額回報?

“瘋狂燒錢”并不能成為公司持續虧損的理由,反而可能成為公司升級轉型的關鍵所在。 上周三,特斯拉發布第四季度財報,其后特斯拉CEO馬斯克在電話會議上表示,特斯拉虧損收窄,營收同比增長88%,但與此同時其首…

android gravity參數,Gravity - [ Android中文手冊 ] - 在線原生手冊 - php中文網

Gravity版本:Android 4.0 r1結構繼承關系public class Gravity extends Objectjava.lang.Objectandroid.view.Gravity類概述用來在一個更大容器中布置對象的標準常量和工具。常量public static final intAXIS_CLIP原始位控制右/底邊界是否被剪切到它的容器中&#x…

Diango博客--8.解鎖博客側欄

文章目錄0.思路引導1.[最新文章] 模板標簽2.[歸檔] 模板標簽3.[分類] 模板標簽4.[標簽云] 模板標簽5.使用自定義的模板標簽0.思路引導 博客側邊欄有四項內容:最新文章、歸檔、分類和標簽云,效果展示如下: 這些內容相對比較固定和獨立&…

十五、詳述 IntelliJ IDEA 插件的安裝及使用方法

正文 首先,進入插件安裝界面: Mac:IntelliJ IDEA -> Preferences -> Plugins;Windows:File -> Settings -> Plugins.標注 1:顯示 IntelliJ IDEA 的插件分類, All plugins:顯示 Inte…

編程巨星的唯一秘訣

別以為是那些軟件開發定律,別以為是開發出那些特殊用途的軟件,別以為是軟件設計技術本身。只有一條真理決定了一個軟件程序員的成功還是失敗。由于堅持這個真理,一個資深的程序員能在一天的時間里學會一門新的編程語言,而由于不堅…

面向數據流的設計方法

面向數據流的設計方法的目標是給出設計軟件結構的一個系統化的途徑。 在軟件工程的需求分析階段,信息流是一個關鍵考慮。通常用數據流圖描繪信息在系統中加工和流動的 情況。面向數據流的設計方法定義了一些不同的“映射”,利用這些映射可以把數據流圖…

AI研究的盲點:無解的神經網絡內在邏輯

論人工神經網絡內在邏輯的研究歷史及現狀。 伴隨著大數據,人工智能(AI)在沉寂了多年之后,又迎來了新的高潮。在這場涉及大部分科學的革命中,人工神經網絡釋放了人工智能(AI)。但科學家們發現&a…

Diango博客--9.歸檔、分類和標簽頁

文章目錄0.思路引導1.回顧2.歸檔頁面3.分類頁面4.標簽頁面0.思路引導 側邊欄已經正確地顯示了最新文章列表、歸檔、分類、標簽等信息,現在來完善歸檔、分類和標簽功能。 當用戶點擊歸檔下的某個日期、分類欄目下的某個分類或者標簽欄目下的某個標簽時,…

android studio1.2.6,1.2.2 使用Android Studio開發Android APP | 菜鳥教程

寫在前面本節將介紹如何使用Android Studio開發Android APP,和前面Eclipse ADT SDK搭建Android開發環境一樣,本節也只是介紹一些基本東西,深入的,比如快捷鍵,小技巧等會再另一篇文章中詳細地介紹!1.下載A…

軟件工程中的啟發規則

1.改進軟件結構提高模塊獨立性 2. 模塊規模應該適中 3.深度、寬度、扇出和扇入都應適當 4.模塊的作用域應該在控制域之內 5.力爭降低模塊接口的復雜程度 6.設計單入口單出口的模塊 7.模塊功能應該可以預測

C#指南,重溫基礎,展望遠方!(4)表達式

表達式是在操作數和運算符的基礎之上構造而成。 表達式的運算符指明了向操作數應用的運算。 運算符的示例包括 、-、*、/ 和 new。 操作數的示例包括文本、字段、局部變量和表達式。 如果表達式包含多個運算符,那么運算符的優先級決定了各個運算符的計算順序。 例如…

UPS開始嘗試“貨車+無人機”的投遞方式,不必再擔心快遞員離職了

繼亞馬遜“空中倉庫”,無人機送貨再現新形式。 作為世界上最大的快遞承運商與包裹遞送公司,UPS當然也沒有放過“送貨無人機”這一新穎業務。與亞馬遜推出“空中倉庫”的理念類似,UPS并沒有選擇讓無人機從倉庫直接起飛,而是將之與…

技術人員如何"正確"的浪費時間?

蘋果產品用戶要浪費時間,你就應該這樣做:買個有鎖的 iPhone ,每天刷幾百次威鋒網等待越獄或解鎖,看到新 App 就安裝,程序提示更新立刻升級;有新的固件(哪怕是 β 版)就壓制不住升級的欲望;每次 …