Java?面向?qū)ο笸ㄟ^new揭開對(duì)象實(shí)例化
更正說明:
我之前的的標(biāo)題有點(diǎn)文不對(duì)題,我這篇博客的內(nèi)容明明說的是:java中對(duì)象創(chuàng)建的過程,對(duì)內(nèi)存之種底層的東西,我其實(shí)提的不太多。
所以我原來的標(biāo)題:《當(dāng)你實(shí)例化對(duì)象時(shí),在內(nèi)存中到底發(fā)生了什么》是不合適的
概念了解
想要知道內(nèi)存中發(fā)生了什么,我們先來了解兩個(gè)內(nèi)存概念????
- 堆內(nèi)存:保存對(duì)象的屬性內(nèi)容。堆內(nèi)存需要用new關(guān)鍵字來分配空間;
- 棧內(nèi)存:保存的是堆內(nèi)存的地址(在這里為了分析方便,可以簡(jiǎn)單理解為棧內(nèi)存保存的是對(duì)象的名字)。
Student student1 = new Student()
這行代碼可以分為兩部分
1、Student student1 聲明對(duì)象,會(huì)在棧上開辟一塊區(qū)域,名叫student1,里面存了:堆中開辟的內(nèi)存的地址??
2、new Student() 實(shí)例化student1對(duì)象,在堆里開辟了一塊區(qū)域,名叫student1??
當(dāng)用等號(hào)將兩者關(guān)聯(lián)的時(shí)候,其實(shí)就是將棧上聲明的對(duì)象student1,指向堆上實(shí)例化的具體空間
如圖所示:
從圖中也可以看出,在“=”關(guān)聯(lián)的時(shí)候,就是將堆中student1開辟內(nèi)存的地址0X99存放到了棧里,可以吧內(nèi)存地址看成Student類的一把鑰匙??
實(shí)例化后對(duì)象student1獲得了這把鑰匙,所以可以在類中任意拿東西,即調(diào)用屬性、方法等??
(大多數(shù)情況下可以這么認(rèn)為,其實(shí)變量名student1儲(chǔ)存的不一定是地址??)
第一種情況
因此可以通過對(duì)象名 student1 ,給堆中的具體成員變量賦值、調(diào)用??。
其實(shí)棧中存放的就是堆中某一個(gè)內(nèi)存的引用,這就是對(duì)象引用的概念,其中的 student1 也被稱作對(duì)象的引用變量??
class Student { String name; //學(xué)生類的屬性 int age; public void eat() { System.out.println(name + "在吃飯, 他" + age + "歲了"); // 學(xué)生類的行為(方法) } } public class TestDemo3 { // 不同的實(shí)例化對(duì)象在棧中擁有不同的空間,他們也指向堆中不同的內(nèi)存地址 public static void main(String[] args) { Student student1 = new Student(); // 學(xué)生對(duì)象student1 student1.name = "小強(qiáng)"; // 通過 對(duì)象名.屬性 來給堆中的具體成員變量賦值 student1.age = 18; student1.eat(); // 調(diào)用類中的eat()方法 Student student2 = new Student(); // 學(xué)生對(duì)象student2 student2.name = "小紅"; student2.age = 23; student2.eat(); } }
第二種情況
不同的實(shí)例化對(duì)象在棧中擁有不同的空間,他們也指向堆中不同的內(nèi)存地址,但是也可以有這樣的情況:棧中有不同的空間,他們指向堆中同一個(gè)內(nèi)存地址??。
class Dog { String name; int age; public void show() { System.out.println("姓名:" + name + " 年齡: " + age); } } public class TestDemo4 { public static void main(String[] args) { Dog one = new Dog(); Dog two = one; } }
對(duì)象one在實(shí)例化后,擁有一塊棧的空間,空間里存放堆的一個(gè)內(nèi)存地址??
那么將one賦值給two之后,two的棧的空間里,也會(huì)存放one擁有的堆的內(nèi)存地址??。
用一個(gè)很形象的比喻,妻子帶著一幅畫嫁給了丈夫,那么她的畫也就屬于丈夫了,兩人共有??。
不論是丈夫還是妻子,只要是對(duì)畫做出了最后的更改,那么這幅畫的內(nèi)容就會(huì)改變。即最后一次修改是有效的,會(huì)覆蓋掉原先的內(nèi)容??
用代碼來展示:
class Dog { String name; int age; public void show() { System.out.println("姓名:" + name + " 年齡: " + age); } } public class TestDemo4 { public static void main(String[] args) { Dog one = new Dog(); Dog two = one; one.name = "阿黃"; one.age = 10; two.name = "旺財(cái)"; two.age = 3; one.show(); System.out.println("========這是分割線========"); two.show(); } }
怎么樣!通過對(duì)象one對(duì)姓名和年齡的賦值是不是被覆蓋掉了,內(nèi)存中的場(chǎng)景大概是這樣
棧中的對(duì)象one、two同時(shí)指向堆中的同一塊空間,也就是不同的??梢孕薷耐粔K堆內(nèi)存的內(nèi)容??,這樣堆內(nèi)存的內(nèi)容自然就是最后對(duì)象two所賦值的內(nèi)容了??。
哈哈! 原來在我們實(shí)例化new一個(gè)對(duì)象的時(shí)候,內(nèi)存里偷偷干了這么多事啊??!
各位鐵汁們,我們下篇博客見,嘻嘻??
到此這篇關(guān)于Java 通過new揭開對(duì)象實(shí)例化的文章就介紹到這了,更多相關(guān)Java 對(duì)象實(shí)例化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java基于JDBC連接Oracle 11g Release2實(shí)例分析
這篇文章主要介紹了java基于JDBC連接Oracle 11g Release2的方法,實(shí)例分析了JDBC連接Oracle 11g Release2容易出現(xiàn)的異常與解決方法,需要的朋友可以參考下2015-06-06SpringMVC中@ModelAttribute與@RequestBody的區(qū)別及說明
這篇文章主要介紹了SpringMVC中@ModelAttribute與@RequestBody的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11向Spring IOC 容器動(dòng)態(tài)注冊(cè)bean實(shí)現(xiàn)方式
這篇文章主要為大家介紹了向Spring IOC 容器動(dòng)態(tài)注冊(cè)bean實(shí)現(xiàn)方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Servlet簡(jiǎn)單實(shí)現(xiàn)登錄功能
這篇文章主要為大家詳細(xì)介紹了Servlet簡(jiǎn)單實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03Java List簡(jiǎn)介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Java中可變數(shù)組的原理就是不斷的創(chuàng)建新的數(shù)組,將原數(shù)組加到新的數(shù)組中,下文對(duì)Java List用法做了詳解。需要的朋友參考下吧2017-05-05SpringData如何通過@Query注解支持JPA語句和原生SQL語句
這篇文章主要介紹了SpringData如何通過@Query注解支持JPA語句和原生SQL語句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11