最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java常量池詳解

 更新時間:2021年09月10日 12:01:33   作者:pluto_blog  
下面小編就為大家?guī)硪黄獪\談java常量池。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

java中有幾種不同的常量池,以下的內容是對java中幾種常量池的介紹,其中最常見的就是字符串常量池。

(1)class常量池

在Java中,Java類被編譯后就會形成一份class文件;class文件中除了包含類的版本、字段、方法、接口等描述信息外,還有一項信息就是常量池,用于存放編譯器生成的各種字面量和符號引用,每個class文件都有一個class常量池。

其中字面量包括:1.文本字符串 2.八種基本類型的值 3.被聲明為final的常量等;

符號引用包括:1.類和方法的全限定名 2.字段的名稱和描述符 3.方法的名稱和描述符。

(2)運行時常量池

運行時常量池存在于內存中,也就是class常量池被加載到內存之后的版本,是方法區(qū)的一部分(JDK1.8 運行時常量池在元空間,元空間也是方法區(qū)的一種實現(xiàn))。不同之處是:它的字面量可以動態(tài)的添加(String類的intern()),符號引用可以被解析為直接引用。

JVM在執(zhí)行某個類的時候,必須經過加載、連接、初始化,而連接又包括驗證、準備、解析三個階段。而當類加載到內存中后,jvm就會將class常量池中的內容存放到運行時常量池中,這里所說的常量包括:基本類型包裝類(包裝類不管理浮點型,整形只會管理-128到127)和字符串類型(即通過String.intern()方法可以強制將String放入常量池),運行時常量池是每個類私有的。在解析階段,會把符號引用替換為直接引用。

(3)基本類型包裝類常量池

Java 基本類型的包裝類的大部分都實現(xiàn)了常量池技術。Byte,Short,Integer,Long這 4 種包裝類默認創(chuàng)建了數(shù)值 [-128,127] 的相應類型的緩存數(shù)據(jù),Character創(chuàng)建了數(shù)值在[0,127]范圍的緩存數(shù)據(jù),Boolean直接返回True或False,如果超出對應范圍就會去創(chuàng)建新的對象。兩種浮點數(shù)類型的包裝類Float,Double并沒有實現(xiàn)常量池技術。

Integer 緩存源碼:

/**
*此方法將始終緩存-128 到 127(包括端點)范圍內的值,并可以緩存此范圍之外的其他值。
*/
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
      return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];
}

舉個栗子:

Integer i1 = 40;
  Integer i2 = 40;
  Integer i3 = 0;
  Integer i4 = new Integer(40);
  Integer i5 = new Integer(40);
  Integer i6 = new Integer(0);
  System.out.println("i1=i2   " + (i1 == i2));
  System.out.println("i1=i2+i3   " + (i1 == i2 + i3));
  System.out.println("i1=i4   " + (i1 == i4));
  System.out.println("i4=i5   " + (i4 == i5));
  System.out.println("i4=i5+i6   " + (i4 == i5 + i6));   
  System.out.println("40=i5+i6   " + (40 == i5 + i6));

結果:

i1=i2         true
i1=i2+i3   true
i1=i4        false
i4=i5        false
i4=i5+i6   true
40=i5+i6   true

解釋:1-4語句結果應該很顯然,因為Integer i1=40 這一行代碼會發(fā)生裝箱,也就是說這行代碼等價于 Integer i1=Integer.valueOf(40),Integer.valueOf()方法基于減少對象創(chuàng)建次數(shù)和節(jié)省內存的考慮,緩存了[-128,127]之間的數(shù)字,如果在此數(shù)字范圍內直接返回緩存中的對象。在此之外,直接new出來,顯然40在常量池的緩存[-128,127]范圍內;因此,i1 直接使用的是常量池中的對象。而Integer i1 = new Integer(40) 會直接創(chuàng)建新的對象;語句 i4 == i5 + i6,因為+這個操作符不適用于 Integer 對象,首先 i5 和 i6 進行自動拆箱操作,進行數(shù)值相加,即 i4 == 40。然后 Integer 對象無法與數(shù)值進行直接比較,所以 i4 自動拆箱轉為 int 值 40,最終這條語句轉為 40 == 40 進行數(shù)值比較,所以結果為true。第六條語句同理。

額外說明:所有整型包裝類對象之間值的比較,全部使用 equals 方法比較。

對于Integer var = ?在-128至127之間的賦值,Integer對象是在 IntegerCache.cache產生,會復用已有對象,這個區(qū)間內的Integer值可以直接使用==進行判斷,但是這個區(qū)間之外的所有數(shù)據(jù),都會在堆上產生,并不會復用已有對象,推薦使用equals方法進行判斷。

(4)字符串常量池

在JDK1.6及之前版本,字符串常量池存放在方法區(qū)中的,在JDK1.7版本以后,字符串常量池被移到了堆中了。

HotSpot VM里,記錄interned string的一個全局表叫做StringTable,它本質上就是個HashSet<String>;這個StringTable在每個HotSpot VM的實例只有一份,被所有的類共享。

注意:它只存儲對java.lang.String實例的引用,而不存儲String對象的內容

字符串常量池和上面的基本類型包裝類常量池有些不同,字符串常量池中沒有事先緩存一些數(shù)據(jù),而是如果要創(chuàng)建的字符串在常量池內存在就返回對象的引用,如果不存在就創(chuàng)建一個放在常量池中;

在Java中,有兩種創(chuàng)建字符串對象的方法,一種是字面量直接創(chuàng)建,另一種是new一個String對象,這兩種方法創(chuàng)建字符串對象的過程會不一樣;

(1)String str = "abc";
(2)String str = new String("abc");

如果是第一種方式創(chuàng)建對象,因為是字面量直接創(chuàng)建,所以在編譯的時候是確定的,如果該字符串不在常量池中會將該字符串放入常量池中并返回字符串對象的引用,如果在常量池中直接返回字符串對象的引用,如果是第二種方式創(chuàng)建對象,因為要創(chuàng)建String類型的對象,String對象是在運行時才加載到內存的堆中的,屬于運行時創(chuàng)建,所以要先在堆中創(chuàng)建一個String對象,再去常量池中尋找是否有相同的字符串,如果有就返回堆中Sring對象的引用,如果沒有則在將該字符串加入常量池中。

舉個栗子:

比較下列兩種創(chuàng)建字符串的方法:

String str1 = new String("abc");

String str2 = "abc";

答案:第一種是用new()來新建對象的,它會在存放于堆中。每調用一次就會創(chuàng)建一個新的對象。 運行時期創(chuàng)建 。

第二種是先在棧中創(chuàng)建一個對String類的對象引用變量str2,然后通過符號引用去字符串常量池里找有沒有”abc”,如果沒有,則將”abc”存放進字符串常量池,并令str2指向”abc”,如果已經有”abc” 則直接令str2指向“abc”?!癮bc”存于常量池在 編譯期間完成 。

String s = new String("abc")
這條語句創(chuàng)建了幾個對象?

答案:共2個。第一個對象是”abc”字符串存儲在常量池中,第二個對象在Java Heap中的 String 對象。這里不要混淆了s是放在棧里面的指向了Heap堆中的String對象。

String s1 = new String("s1") ;

String s1 = new String("s1") ;

上面一共創(chuàng)建了幾個對象?

答案:3個 ,編譯期常量池中創(chuàng)建1個,運行期堆中創(chuàng)建2個.(用new創(chuàng)建的每new一次就在堆上創(chuàng)建一個對象,用引號創(chuàng)建的如果在常量池中已有就直接指向,不用創(chuàng)建)

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • 如何使用Spring MVC的消息轉換器設置日期格式

    如何使用Spring MVC的消息轉換器設置日期格式

    這篇文章主要介紹了如何使用Spring MVC的消息轉換器設置日期格式,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • SpringBoot整合MyBatis四種常用的分頁方式(詳細總結)

    SpringBoot整合MyBatis四種常用的分頁方式(詳細總結)

    這篇文章詳細給大家總結了SpringBoot整合MyBatis四種常用的分頁方式,文中通過代碼示例為大家介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • 關于Java使用Http輕量級請求庫Unirest的方法

    關于Java使用Http輕量級請求庫Unirest的方法

    這篇文章主要介紹了關于Java使用Http輕量級請求庫Unirest的方法,Unirest 是一個輕量級的 HTTP 請求庫,可發(fā)起 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS 請求,支持 Node、Ruby、Java、PHP、Python、Objective-C、.NET 等多種語言,需要的朋友可以參考下
    2023-08-08
  • mybatis?log4j2打印sql+日志實例代碼

    mybatis?log4j2打印sql+日志實例代碼

    在學習mybatis的時候,如果用log4j2來協(xié)助查看調試信息,則會大大提高學習的效率,加快debug速度,下面這篇文章主要給大家介紹了關于mybatis?log4j2打印sql+日志的相關資料,需要的朋友可以參考下
    2022-08-08
  • 簡單理解Java的垃圾回收機制與finalize方法的作用

    簡單理解Java的垃圾回收機制與finalize方法的作用

    這篇文章主要介紹了簡單理解Java的垃圾回收機制與finalize方法的作用,著重講解了Java的GC銷毀對象的過程,需要的朋友可以參考下
    2015-11-11
  • Java實現(xiàn)五子棋的基礎方法

    Java實現(xiàn)五子棋的基礎方法

    這篇文章主要為大家詳細介紹了Java實現(xiàn)五子棋的基礎方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • spring?cloud中Feign導入jar失敗的問題及解決方案

    spring?cloud中Feign導入jar失敗的問題及解決方案

    這篇文章主要介紹了spring?cloud中Feign導入jar失敗的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Jenkins與SVN持續(xù)集成的示例代碼

    Jenkins與SVN持續(xù)集成的示例代碼

    這篇文章主要介紹了Jenkins與SVN持續(xù)集成的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 如何使用hutool做本地緩存的工具類

    如何使用hutool做本地緩存的工具類

    這篇文章主要介紹了如何使用hutool做本地緩存的工具類,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Spring?Boot+Aop記錄用戶操作日志實戰(zhàn)記錄

    Spring?Boot+Aop記錄用戶操作日志實戰(zhàn)記錄

    在Spring框架中使用AOP配合自定義注解可以方便的實現(xiàn)用戶操作的監(jiān)控,下面這篇文章主要給大家介紹了關于Spring?Boot+Aop記錄用戶操作日志實戰(zhàn)的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04

最新評論

宁强县| 司法| 沈阳市| 皮山县| 交口县| 盐山县| 洪江市| 嘉禾县| 漾濞| 江阴市| 航空| 永平县| 县级市| 鄂温| 克什克腾旗| 安康市| 菏泽市| 临洮县| 同江市| 成都市| 上犹县| 昭觉县| 南投县| 喀喇| 临沂市| 榆中县| 平凉市| 大丰市| 宜丰县| 克山县| 芦溪县| 武汉市| 大理市| 新营市| 登封市| 临邑县| 德化县| 刚察县| 商洛市| 连城县| 周宁县|