一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - JDK源碼分析之String、StringBuilder和StringBuffer

JDK源碼分析之String、StringBuilder和StringBuffer

2021-05-03 11:16ashleyboy Java教程

這篇文章主要給大家介紹了關于JDK源碼分析之String、StringBuilder和StringBuffer的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用jdk具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

本文主要介紹了關于jdk源碼分析之string、stringbuilder和stringbuffer的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧

string類的申明

?
1
2
public final class string
 implements java.io.serializable, comparable<string>, charsequence {…}

string類用了final修飾符,表示它不可以被繼承,同時還實現了三個接口, 實現serializable接口表示string類可被序列化;實現comparable<t> 接口主要是提供一個compareto 方法用于比較string字符串;還實現了charsequence 接口,這個接口代表的是char值得一個可讀序列(charbuffer, segment, string, stringbuffer, stringbuilder也都實現了charsequence接口)

string主要字段、屬性說明

?
1
2
3
4
5
6
7
8
/*字符數組value,存儲string中實際字符 */
private final char value[];
/*字符串的哈希值 默認值0*/
private int hash;
/*字符串的哈希值 默認值0*/
/*一個比較器,用來排序string對象, comparetoignorecase方法中有使用 */
public static final comparator<string> case_insensitive_order
      = new caseinsensitivecomparator();

string 部分方法分析

string類提供了系列的構造函數,其中有幾個都已經不推薦使用了,如下圖:

JDK源碼分析之String、StringBuilder和StringBuffer

構造函數

以下是兩個常用的構造函數的實現:

?
1
2
3
4
5
6
7
8
9
10
11
//string str = new string(“123”)
public string(string original) {
  this.value = original.value;
  this.hash = original.hash;
}
 
//string str3 = new string(new char[] {'1','2','3'});
public string(char value[]) {
   //將字符數組值copy至value
  this.value = arrays.copyof(value, value.length);
 }

boolean equals(object anobject)

 string 類重寫了 equals 方法,將此字符串與指定的對象比較。當且僅當該參數不為 null,并且是與此對象表示相同字符序列的 string 對象時,結果才為 true。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public boolean equals(object anobject) {
  //直接將對象引用相比較,相同返回true
  if (this == anobject) {
   return true;
  }
  //比較當前對象與anobject的字符序列value
  if (anobject instanceof string) {
   string anotherstring = (string)anobject;
   int n = value.length;
   if (n == anotherstring.value.length) {
    char v1[] = value;
    char v2[] = anotherstring.value;
    int i = 0;
    while (n-- != 0) {
     if (v1[i] != v2[i])
      return false;
     i++;
    }
    return true;
   }
  }
  return false;
 }

int compareto(string anotherstring)

 逐位比較兩個字符串的字符序列,如果某一位字符不相同,則返回該位的兩個字符的unicode 值的差,所有位都相同,則計算兩個字符串長度之差,兩個字符串相同則返回0

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public int compareto(string anotherstring) {
  int len1 = value.length;
  int len2 = anotherstring.value.length;
  //取長度較小的字符串的長度
  int lim = math.min(len1, len2);
  char v1[] = value;
  char v2[] = anotherstring.value;
 
  int k = 0;
  while (k < lim) {
   //將兩個字符串的字符序列value逐個比較,如果不等,則返回該位置兩個字符的unicode 之差
   char c1 = v1[k];
   char c2 = v2[k];
   if (c1 != c2) {
    return c1 - c2; //返回unicode 之差
 
   }
   k++;
  }
  //長度較小的字符串所有位都比較完,則返回兩個字符串長度之差
  //如果兩個字符串相同,那么長度之差為0,即相同字符串返回0
  return len1 - len2;
 }

comparetoignorecase(string str)方法實現于此類似,比較時忽略字符的大小寫,實現方式如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public int compare(string s1, string s2) {
   int n1 = s1.length();
   int n2 = s2.length();
   int min = math.min(n1, n2);
   for (int i = 0; i < min; i++) {
    char c1 = s1.charat(i);
    char c2 = s2.charat(i);
    if (c1 != c2) {
     c1 = character.touppercase(c1);
     c2 = character.touppercase(c2);
     if (c1 != c2) {
      c1 = character.tolowercase(c1);
      c2 = character.tolowercase(c2);
      if (c1 != c2) {
       // no overflow because of numeric promotion
       return c1 - c2;
      }
     }
    }
   }
   return n1 - n2;
  }

native string intern()

當調用 intern 方法時,如果池已經包含一個等于此 string 對象的字符串(用 equals(object) 方法確定),則返回池中的字符串。否則,將此 string 對象添加到池中,并返回此 string 對象的引用。

所有字面值字符串和字符串賦值常量表達式都使用 intern 方法進行操作,例如:string str1 = "123";

string內存位置:常量池or堆

string對象可以直接通過字面量創建,也可以通過構造函數創建,有什么區別呢?

 1.通過字面量或者字面量字符串通過”+”拼接的方式創建的string對象存儲在常量池中,實際創建時如果常量池中存在,則直接返回引用,如果不存在則創建該字符串對象

 2.使用構造函數創建字符串對象,則直接在堆中創建一個string對象

 3.調用intern方法,返回則會將該對象放入常量池(不存在則放入常量池,存在則返回引用)

下面舉例說明string對象內存分配情況:

?
1
2
3
4
5
6
7
string str1 = new string("123");
  string str2 = "123";
  string str3 = "123";
  string str4 = str1.intern();
  system.out.println(str1==str2); // false str1在堆中創建對象,str2在常量池中創建對象
  system.out.println(str2==str3); // true str2在常量池中創建對象,str3直接返回的str2創建的對象的引用 所以str2和str3指向常量池中同一個對象
  system.out.println(str4==str3); // true str4返回常量池中值為"123"的對象,因此str4和str2、str3都相等

JDK源碼分析之String、StringBuilder和StringBuffer

關于字符串拼接示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class stringtest {
 public static final string x = "abc"; // 常量x
 @test
 public void test() {
 
  string str5 = new string("abc");
  string str6 = str5+"def"; //堆中創建
  string str7 = "abc"+"def"; //常量池
  string str8 = x+"def"//x為常量,值是固定的,因此x+"def"值已經定下來為abcdef,實際上編譯后得代碼相當于string str8 = "abcdef"
  string str9 = "abc"
  string str10 = str9+"def"; //堆中
  
  system.out.println(str6==str7); //false
  system.out.println(str8==str7); //true
  system.out.println(str10==str7); //false
 
  system.out.println(x==str9); //true
} }

反編譯后的代碼看一下便一目了然:

JDK源碼分析之String、StringBuilder和StringBuffer

內存分配如下:

 JDK源碼分析之String、StringBuilder和StringBuffer

string、stringbuffer、stringbuilder

 由于string類型內部維護的用于存儲字符串的屬性value[]字符數組是用final來修飾的:

?
1
2
/** the value is used for character storage. */
private final char value[];

表明在賦值后可以再修改,因此我們認為string對象一經創建后不可變,在開發過程中如果碰到頻繁的拼接字符串操作,如果使用string提供的contact或者直接使用”+”拼接字符串會頻繁的生成新的字符串,這樣使用顯得低效。java提供了另外兩個類:stringbuffer和stringbuilder,用于解決這個問題:

看一下下面的代碼:

?
1
2
3
4
5
6
7
8
9
string str1="123";
   string str2="456";
   string str3="789";  
   string str4 = "123" + "456" + "789"; //常量相加,編譯器自動識別 string str4=“123456789”  
   string str5 = str1 + str2 + str3; //字符串變量拼接,推薦使用stringbuilder  
   stringbuilder sb = new stringbuilder();
   sb.append(str1);
   sb.append(str2);
   sb.append(str3);

下面是stringbuilder類的實現,只截取了分析的部分代碼:

?
1
2
3
4
5
6
7
8
9
public final class stringbuilder
 extends abstractstringbuilder
 implements java.io.serializable, charsequence
{
 
 //拼接字符串
 @override
 public stringbuilder append(string str) {
 //調用父類abstractstringbuilder.append super.append(str); return this; } }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
abstract class abstractstringbuilder implements appendable, charsequence {
 /**
  * 存儲字符串的字符數組,非final類型,區別于string類
  */
 char[] value;
 
 /**
  * the count is the number of characters used.
  */
 int count;
 
 public abstractstringbuilder append(string str) {
  if (str == null)
   return appendnull();
  int len = str.length();
   //檢查是否需要擴容
  ensurecapacityinternal(count + len);
  //字符串str拷貝至value 
  str.getchars(0, len, value, count);
  count += len;
  return this;
}
 
 
 private void ensurecapacityinternal(int minimumcapacity) {
  // overflow-conscious code
  // minimumcapacity=count+str.length
  //拼接上str后的容量 如果 大于value容量,則擴容
  if (minimumcapacity - value.length > 0) {
    
    //擴容,并將當前value值拷貝至擴容后的字符數組,返回新數組引用
   value = arrays.copyof(value,
     newcapacity(minimumcapacity));
  }
 }
 
 //stringbuilder擴容
 private int newcapacity(int mincapacity) {
  // overflow-conscious code
  // 計算擴容容量
  // 默認擴容后的數組長度是按原數(value[])組長度的2倍再加上2的規則來擴展,為什么加2?
  int newcapacity = (value.length << 1) + 2;
  if (newcapacity - mincapacity < 0) {
   newcapacity = mincapacity;
  }
  return (newcapacity <= 0 || max_array_size - newcapacity < 0)
   ? hugecapacity(mincapacity)
   : newcapacity;
 }
}

stringbuffer和stringbuilder用一樣,內部維護的value[]字符數組都是可變的,區別只是stringbuffer是線程安全的,它對所有方法都做了同步,stringbuilder是線程非安全的,因此在多線程操作共享字符串變量的情況下字符串拼接處理首選用stringbuffer, 否則可以使用stringbuilder,畢竟線程同步也會帶來一定的消耗。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/ashleyboy/p/9063153.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 无码国产成人午夜在线观看不卡 | 国产欧美日韩专区 | 九九九九九九精品免费 | 青青青国产在线 | 晓雪老师我要进你里面好爽 | 国产99精品成人免费视频 | 亚洲国产精品福利片在线观看 | 毛片a级放荡的护士hd | 日韩视频免费一区二区三区 | 国产精品视频免费视频 | 国产在线欧美日韩精品一区二区 | 操美女b| 成人在线一区二区 | 射逼网站 | 精品国产一区二区三区国产馆 | 羞羞漫画免费漫画页面在线看漫画秋蝉 | 亚洲精品国产福利片 | 小小水蜜桃免费影院 | 91东航翘臀女神在线播放 | 国产婷婷成人久久av免费高清 | 欧美男女爱爱视频 | 日本网络视频www色高清免费 | 小小水蜜桃视频高清在线观看免费 | 国产人妖ts在线视频网 | 91制片厂免费观看 | 日韩亚洲欧美理论片 | 日本免费一区二区三区 | 毛片资源站 | 亚洲视频在线观看地址 | 国产精品视频1区 | 91精品国产综合久久精品 | 精品无码乱码AV | 999久久精品国产 | 色综合天天综合网站中国 | 女女同性做爰xxoo亲吻 | 久久久久激情免费观看 | 日本三级大学生17 | 午夜香蕉成视频人网站高清版 | 男人与雌性宠物交啪啪小说 | 国产成人在线播放 | 天天视频国产精品 |