Javase高級(jí)教程:for循環(huán)創(chuàng)建對(duì)象

Javase高級(jí)教程:for循環(huán)創(chuàng)建對(duì)象

長沙牛耳教育      2022-05-06 08:00:01     50

Javase高級(jí)教程:for循環(huán)創(chuàng)建對(duì)象,  有時(shí)候奇怪的發(fā)現(xiàn)往list添加數(shù)據(jù)的時(shí)候,一直被最后一個(gè)元素覆蓋,首先,我們得明白原理:  在new一個(gè)對(duì)象的時(shí)候,對(duì)象的ID

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹


  有時(shí)候奇怪的發(fā)現(xiàn)往list添加數(shù)據(jù)的時(shí)候,一直被最后一個(gè)元素覆蓋,首先,我們得明白原理:


  在new一個(gè)對(duì)象的時(shí)候,對(duì)象的ID是唯一確定的;將對(duì)象add入list中時(shí),放入list中的其實(shí)是對(duì)象的引用;而每次循環(huán)只是簡(jiǎn)單的set對(duì)象的屬性,set新的屬性值,而add進(jìn)list中的對(duì)象還是同一個(gè)對(duì)象id,也就是同一個(gè)對(duì)象;


  所以每次add之后,list發(fā)現(xiàn)對(duì)象引用和之前元素一樣,就覆蓋掉了之前add的對(duì)象。所以循環(huán)之后list中的對(duì)象是重復(fù)的對(duì)象。


  想要避免這個(gè)問題只要每次add時(shí)保證對(duì)象引用都是不同的即可,即每循環(huán)一次重新new一個(gè)對(duì)象。


  new的對(duì)象應(yīng)該放在for循環(huán)內(nèi),每循環(huán)一次重新new一個(gè)新對(duì)象



  它的確是在main方法棧中先后創(chuàng)建了10個(gè)引用叫obj,然后每個(gè)obj指向不同的new出來的對(duì)象。


  關(guān)鍵是:每次循環(huán)體執(zhí)行完后,循環(huán)體內(nèi)定義的代碼塊局部變量、對(duì)象如果沒有被繼續(xù)引用,就立即被銷毀了;即obj變量、new出來的對(duì)象都被銷毀了。


  一般是循環(huán)一次一個(gè)新對(duì)象,所以如非必要,不要在循環(huán)里面創(chuàng)建對(duì)象。


  用內(nèi)存角度來解釋的話,在JVM的方法棧和堆內(nèi)存這兩個(gè)內(nèi)存中,當(dāng)運(yùn)行Objectobj=newObject();時(shí),在方法棧的棧頂中放入Objectobj,然后在堆中生成一個(gè)Object對(duì)象,最后方法棧中的obj指向Object對(duì)象,這時(shí)完成一次循環(huán)的內(nèi)存動(dòng)作。接著第二次循環(huán),newObject();又產(chǎn)生一個(gè)新的Object對(duì)象,然后方法棧中的obj指向新的Object對(duì)象,第一次循環(huán)的Object對(duì)象沒有被任務(wù)變量引用,成為了垃圾,等JVM垃圾回收器回收。其它循環(huán)以此類推了。


  在這里我提一下題外話,JVM有個(gè)優(yōu)秀的算法是,JVM的方法棧,一個(gè)方法的調(diào)用產(chǎn)生一個(gè)棧幀,這個(gè)棧幀在方法調(diào)用時(shí)計(jì)算出你有幾個(gè)局部變量,這個(gè)計(jì)算會(huì)過濾作用域的,如你的循環(huán)后面再建立一個(gè)局部變量,那JVM認(rèn)為只有一個(gè)局部變量,因?yàn)槟愕腛bjectobj=newObject();在大括號(hào)內(nèi),出了大括號(hào)就沒有了,所以只需要一個(gè)位置來存放局部變量即可,也就是說運(yùn)行到大括號(hào)時(shí)用這個(gè)位置來執(zhí)行代碼,出了大括號(hào)后下一個(gè)局部變量就可以接著使用這個(gè)棧的這個(gè)位置來執(zhí)行下面的代碼了


  再看一個(gè)例子:



  結(jié)果:



  解釋:


  在for循環(huán)內(nèi)部創(chuàng)建的話,每次執(zhí)行循環(huán)都會(huì)創(chuàng)建對(duì)象,沒什么特別明顯壞處,只是會(huì)消耗內(nèi)存。所以我們通常在for循環(huán)外部實(shí)例化對(duì)象,因?yàn)樗鼒?zhí)行一次


  Objectobj是創(chuàng)建對(duì)象引用,引用的實(shí)例地址。newObject();是創(chuàng)建對(duì)象實(shí)例


  兩者都會(huì)占用系統(tǒng)資源。


  改進(jìn)之前for循環(huán)中創(chuàng)建了10次引用和10實(shí)例,改進(jìn)后是創(chuàng)建了1次引用,10實(shí)例。


  在方法執(zhí)行完后內(nèi)存資源會(huì)被回收


    以上就是長沙牛耳教育Java培訓(xùn)機(jī)構(gòu)小編介紹的“Javase高級(jí)教程:for循環(huán)創(chuàng)建對(duì)象”的內(nèi)容,希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。


Java教程 Java基礎(chǔ)教程

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。