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