1. 程式人生 > >JDK原始碼分析之String(一)

JDK原始碼分析之String(一)

摘要

日常使用java中,java.lang.String類幾乎是使用最為頻繁的一個類,此係列主要介紹String的具體實現以及作者對其進行了什麼樣的優化操作。

實現

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
private int hash;
private static final
long serialVersionUID = -6849794470754667710L; private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; //其他函式 ...... }

String的一些基本資訊

1.String被final修飾符修飾,表示String是一個不可變類,一旦建立,就無法修改其中的內容。
2.實現了java.io.Serializable, Comparable<String>, CharSequence三個介面
3.String中儲存核心內容的資料結構是一個char陣列。

String的不可變特性

前面說到String由final修飾,並且所有可能更改其核心儲存內容的char[]陣列的方法的返回值全都是返回一個新的字串,保證了char[]無法被修改。
測試程式碼

public static void main(String[] args) {
        String v="This is a String value!";
        char[] c=new char[]{'a','s','d'};
        change(v,c);
        System.out.println(v);
        System.out
.println(c); } private static void change(String value,char c[]){ value="This is a New String value!"; c[0]='N'; }

為了對比,我們引入char陣列
如果你認為輸出是:

This is a String value!
Nsd

那你就忽略了String類的不可變特性。
首先,我們初始化了一個String和char[]變數,其指向的值分別為This is a String value!a``s``d,呼叫change(String value,char c[])方法時,將雙方的地址傳入方法。
最初,方法引數value指向傳入的引數v,此時傳入的引數v的地址指向This is a String value!的地址,所以value指向的值為This is a String value!。當重新向方法引數value賦值時,由於String的不可變性,方法引數value指向了新地址This is a New String value!。char[]則直接改變了存在記憶體中的內容。函式呼叫完畢,繼續執行下一步。
由於要輸出v的值,此時v依然指向This is a String value!的地址,c指向的也同樣是一開始陣列的地址,而方法體直接改變了地址中的值。
所以輸出應該為

This is a String value!
Nsd

棧區指向的地址不變
上圖中可以瞭解到,棧區指向的地址不變,而只有char[]陣列在記憶體中實際發生了改變。

String的宣告方式

常用的兩種方式

String s1="This is a String value!";
String s2=new String("This is a String value!");

那麼這兩種宣告方式對java來說有什麼不一樣的地方呢?
測試程式碼

String value1="This is a String value!";
String value2="This is a String value!";
String value3=new String("This is a String value!");
System.out.println(value1==value2);
System.out.println(value1==value3);
System.out.println(value2==value3);

輸出

true
false
false

上一節說到==操作符比較的是兩者引用的地址是否一致。
也就是說value1``value2指向的是同一個地址
記憶體中的情況
這是JVM對String的第一處優化。
具體細節,下節再講。

相關推薦

JDK原始碼分析String()

摘要 日常使用java中,java.lang.String類幾乎是使用最為頻繁的一個類,此係列主要介紹String的具體實現以及作者對其進行了什麼樣的優化操作。 實現 public final class String implements jav

jdk原始碼分析collection,List,Set

前言 標題取得有點大,一口氣分析三塊的原始碼,看上去是個很大的話題,不過在個人看來,一方面,這三個都是介面,不涉及程式碼實現,讀起來比較快,另一方面,大家都知道List,Set這兩個介面都繼承自collection,他們之間存在關聯,所以放在一塊分析討論最能凸顯,這三塊介面

SNMP原始碼分析)配置檔案部分

snmpd.conf想必不陌生。在程序啟動過程中會去讀取配置檔案中各個配置。其中幾個引數需要先知道是幹什麼的:   token:配置檔案的每行的開頭,例如 group MyROGroup v1 readSec 這行token的引數是group。  

netty原始碼分析 ByteBuf

終於到最後的ByteBuf了,其實和jdk nio的ByteBuffer  含義大致相同 都是對byte陣列的操作,不同的是ByteBuf定義了兩個下標 讀下標和寫下標 然後再看看其的實現類 WrappedByteBuf 對byteBuf的包裝類 Empt

jdk原始碼閱讀String

String類 域 private final char value[]; private int hash; // Default to 0 private static final long serialVersionUID = -6849794470754667710L; p

JDK原始碼分析String的儲存區與不可變性

// ... literals are interned by the compiler // and thus refer to the same object String s1 = "abcd"; String s2 = "abcd"; s1 == s2; // --> true // ..

JDK原始碼分析ArrayList(二)

ArrayList原始碼分析(二) 這裡是ArrayList的第二部分,介紹remove、clear、sublist、trimToSize、iterator、toArray等方法。 (多看看原始碼有利於對集合類使用的理解~) remove方法 根

Zookeeper原始碼分析持久化()

一、前言   持久化對於資料的儲存至關重要,下面進行詳細分析。二、持久化總體框架   持久化的類主要在包org.apache.zookeeper.server.persistence下,此次也主要是對其下的類進行分析,其包下總體的類結構如下圖所示。   · TxnLog,

JDK原始碼分析主要阻塞佇列實現類PriorityBlockingQueue

PriorityBlockingQueue類也是實現阻塞佇列的一種工具類,同Array BlockingQueue類和LinkedBlockingQueue一樣,最為訊息中介軟體的實現類。同步執行緒之間的訊息。 如果要分析PriorityBlockingQueue就必須要

JDK原始碼分析系列---String,StringBuilder,StringBuffer

1.String public final class String implements java.io.Serializable, Comparable<String>, CharSequence { //儲存字元,final修飾 private final char

Netty原始碼分析ChannelPipeline()—ChannelPipeline的構造與初始化

Netty中ChannelPipeline實際上類似與一條資料管道,負責傳遞Channel中讀取的訊息,它本質上是基於責任鏈模式的設計與實現,無論是IO事件的攔截器,還是使用者自定義的ChannelHandler業務邏輯都做為一個個節點被新增到任務鏈上。 一、ChannelPipeline的設計與構成 &

Netty原始碼分析ByteBuf()—ByteBuf中API及型別概述

ByteBuf是Netty中主要的資料容器與操作工具,也是Netty記憶體管理優化的具體實現,本章我們先從整體上對ByteBuf進行一個概述; AbstractByteBuf是整個ByteBuf的框架類,定義了各種重要的標誌位與API供具體的實現類使用與實現;下面我們就從AbstractByteBuf類入手對

Linux核心原始碼分析set_arch ()

### 1. 概述 之前已經寫了幾篇Linux核心啟動相關的文章,比如:《[解壓核心映象](http://mp.weixin.qq.com/s?__biz=MzUzNjU2OTkyOA==&mid=2247484463&idx=1&sn=1dc7706fccd141ecbdb2704d

步步實現windows版ijkplayer系列文章三——Ijkplayer播放器原始碼分析音視訊輸出——音訊篇

一步步實現windows版ijkplayer系列文章之三——Ijkplayer播放器原始碼分析之音視訊輸出——音訊篇 這篇文章的ijkplayer音訊原始碼研究我們還是選擇Android平臺,它的音訊解碼是不支援硬解的,音訊播放使用的API是OpenSL ES或AudioTrack。 OpenSL ES

原始碼分析基於ArrayList手寫HahMap()

import java.util.ArrayList; import java.util.List; /** * 基於arraylist實現hashmap集合(簡版:效率低) * @author zjmiec * */ public class ExtArrayListHashMap&

原始碼閱讀系列】JDK 8 ConcurrentHashMap 原始碼分析 由transfer引發的bug

不閱讀原始碼就不會發現這個事兒 前段時間在閱讀ConcurrentHashMap原始碼,版本JDK 8,目前原始碼研究已經告一段落。感謝魯道的ConcurrentHashMap原始碼分析文章,讀到文章,感覺和作者發生了一些交流,解答了很多疑惑,也驗證了一些想法。魯道在簡書的addCount分析文章點這裡&n

以太坊go-ethereum原始碼分析p2p模組()

寫了多年程式看了不少開原始碼, 大多數時候都是將知識存於腦中,偶爾做做簡單筆記, 就從這裡開始寫點詳細的技術文章吧. 以前做實時流媒體開發時就想對p2p技術做一些研究, 但是因為公司的流媒體技術使用relay伺服器中轉的模式, 所以一直沒有深入研究, 其實實時

圖解Java常用資料結構()\JDK原始碼分析(二)——LinkedList

最近在整理資料結構方面的知識, 系統化看了下Java中常用資料結構, 突發奇想用動畫來繪製資料流轉過程. 主要基於jdk8, 可能會有些特性與jdk7之前不相同, 例如LinkedList LinkedHashMap中的雙向列表不再是迴環的. HashMap中的單鏈表

Android Wi-Fi原始碼分析WifiService操作Wi-Fi():分析Wifi.c中的wifi_load_driver()函式

Wi-Fi原始碼分析之WifiService操作Wi-Fi(一) 分析Wifi.c中的wifi_load_driver()函式 int wifi_load_driver() { AL

)ghostscript原始碼分析interp()函式的第二個引數

/* Main interpreter. */ /* If execution terminates normally, return e_InterpreterExit. */ /* If an error occurs, leave the current object in *perror_o