目錄java
❝對象的建立,內存佈局以及訪問定位,推導String必問面試題答案程序員
❞
package com.kuaizhan.web.utils;
/** * @author by zengzhiqin * 2020-07-15 */ class Person { String name; public void say(String name) { System.out.println("hello " + name); } } public class TestPerson { public static void main(String[] args){ Person person; person = new Person(); person.say("特朗普"); } } 複製代碼
以此爲例,結合以前說到的類生命週期來講(不懂的朋友能夠看前面的文章Java類的生命週期,不懂這個都很差意思和別人說我是搞JAVA的 ),當執行到 new Person 的時候:web
分配內存 = 從虛擬機設置的堆內存裏面劃分一塊新對象所需的肯定大小的內存
具體的劃分方式根據各家垃圾收集器不一樣也採用不一樣的劃分方式,主要兩種:面試
方式一:指針碰撞(假設JAVA堆內存是整整齊齊的,用過的站一塊兒,沒用過的站一塊兒,那麼在中間分界地方放個指針,每次新分配往沒用過的那邊移動一點就行了。這種方式須要垃圾收集器維護這個用過的和沒用過的內存,由於運行過程當中可能中間隨時有使用過的內存被回收了就出現了缺口,須要垃圾收集器進行整理內存)編輯器
方式二:空閒列表(JAVA堆空閒內存之間是這裏缺一塊那裏缺一塊的,虛擬機維護一個空閒內存列表,記錄下來哪些空閒哪些佔用了,分配的時候從空閒列表裏面找)佈局
仍是這段代碼:flex
package com.kuaizhan.web.utils;
/** * @author by zengzhiqin * 2020-07-15 */ class Person { String name; public void say(String name) { System.out.println("hello " + name); } } public class TestPerson { public static void main(String[] args){ Person person; person = new Person(); person.say("特朗普"); } } 複製代碼
調用過程:優化
注意:url
局部變量 person 其實就是一個reference引用,說白了就是一個相似 0x11 的地址,存在於局部變量表裏面(局部變量表在棧區,不記得的朋友能夠看看上一篇講JVM內存分佈的文章Java跨平臺根本緣由,面試必問JVM內存模型白話文詳解來了)。spa
引用指向關係: 0x11 => 0x22 => 0x33
reference1 就是局部變量person,指向堆區的實例;而後 new Person() 指向方法區裏面的 Person類元數據信息包括sayHello方法。
當調用sayHello的時候,步驟以下三步:
String 面試高頻題,其實都是靠推導出來的,記永遠是記不清的:
String str = "1" + "2" + "3";
答案:一個對象,編譯時候會進行字符串摺疊,算是一個優化,之前確實是四個對象,「1」,「2」,「3」,「123」 字符串摺疊:若是是常量相加,通俗理解就是先加,而後去常量池找,有直接返回,沒有就建立 複製代碼
String s1 = "hello";
String s2 = "world"; String s3 = "hello world"; System.out.print(s3 == "hello" + " world") true,根據上面的分析,都是比較常量池的值,是同一個,true System.out.print(s3 == s1 + s2); false,變量相加,只要有一個變量,那麼都要先給變量開空間,就成了地址比較 複製代碼
String str2 = new String("Trump"); 建立了幾個對象?
String str1 = "Trump";
直接去常量池建立一個Trump,棧裏面保存引用直接指向常量池」Trump「 String str2 = new String("Trump"); 建立幾個對象分狀況(String 不可變): 1. 一個對象(若是常量池中已經存在」Trump」,堆裏面建立個對象就能夠,棧裏面來個引用指向堆) 2. 兩個對象(若是常量池中不存在」Trump「,先在常量池裏面建立」Trump「,而後堆裏面new一個對象,最後棧裏面來個引用指向堆) System.out.print(str1 == str2); 比較的棧裏面的引用地址,指向的東西都不同怎麼多是同樣的,果斷 false System.out.print(str1.equals(str2)); 比較的常量池裏面的值,都是Trump, true 複製代碼
公衆號下篇內容預告:
垃圾回收,JAVA程序員的福音吶
往期推薦:
Java跨平臺根本緣由,面試必問JVM內存模型白話文詳解來了
從JVM設計者的角度來看.class文件結構,一文弄懂.class文件的身份地位
Java類的生命週期,不懂這個都很差意思和別人說我是搞JAVA的
歡迎批評指正,有收穫的朋友點個在看或者分享鼓勵一下吧,十分感謝~