Java 中 String 的構造方法

shaopiing發表於2016-05-01

String 對於所有 Java 程式設計師來說都不會陌生,幾乎每天甚至每個程式都會和 String 打交道,因此將 String 的常用知識彙集在此,方便查閱。

概敘:

Java 中是如此定義 String 的:

public final class String extends Object implements Serializable, Comparable<String>, CharSequence

String 是 final 型別的,繼續看下面的解釋:

The String class represents character strings. 

All string literals in Java programs, such as "abc", are implemented as instances of this class.

Strings are constant; their values cannot be changed after they are created. 

String 物件代表了字元的串或序列,Java 中所有字面量的字串都是 String 的物件;

String 是常量,它的值一旦被建立就不能改變了。

String buffers support mutable strings. Because String objects are immutable they can be shared. 

接下來說字元緩衝區支援可變的字串,因為緩衝區裡面的字串物件們可以被共享(其實就是使物件的引用發生了改變)。

 

在 Java 中,提供了通過字串連線符( + )號,將其他型別的物件轉換成 String 型別:

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java.

int i = 123;
String str2 = i + "abc"; /** * 上面一句生成的 class 檔案如下: * String str2 = (new StringBuilder(String.valueOf(i))).append("abc").toString(); * String 對 “+” 的支援使用了 StringBuilder 以及它的 append 和 toString 方法。 */

表面看似簡單,其實運算複雜,不如直接用 String.valueOf 來的快:

int i = 1;
String strNew = String.valueOf(1) + "abc";

構造方法:

1)無參構造方法

String()
Initializes a newly created String object so that it represents an empty character sequence.

該構造方法會建立空的字元序列,注意這個構造方法的使用,因為創造不必要的字串物件是不可變的。因此不建議採取下面的建立 String 物件:

String str = new String()
str = "sample";

這樣的結果可想而知,產生了不必要的物件。

2)引數為字串型別

String(String original)
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.

源 String 的值不會影響目標 String 的值,但是用到比較少,或許結合 subString 方法使用:

String original = "1234567890";
String str = new String(original.subString(2, 5));

這樣寫是有必要的,當 original 是個大字串時,這種擷取方法可以使得新的字串物件指向新的物件,而不是原來的 original,減少記憶體佔用。

3)引數為 byte 陣列型別

String(byte[] bytes)
Constructs a new String by decoding the specified array of bytes using the platform's default charset.

String(byte[] bytes, Charset charset)
Constructs a new String by decoding the specified array of bytes using the specified charset.

byte 是網路傳輸或儲存的序列化形式,所以在很多傳輸和儲存的過程中需要將 byte[] 陣列和 String 進行相互轉化。

有關 IO 流的程式碼中會出現這個構造方法,字元編碼導致的亂碼問題也是比較多的,這裡需要注意:一旦看到 byte 陣列,一定要想到編碼問題

經常會用到 getBytes(Charset charset) 方法:

try {
  byte[] byteArr = strNew.getBytes("UTF-8");
  String newString = new String(byteArr, "UTF-8");
} catch (UnsupportedEncodingException e) {
  e.printStackTrace();
}

4)引數為 char 陣列型別

String(char[] value)
Allocates a new String so that it represents the sequence of characters currently contained in the character array argument.

這裡值得注意的是:當我們使用字元陣列建立 String 的時候,會用到 Arrays.copyOf 方法或 Arrays.copyOfRange 方法。這兩個方法是將原有的字元陣列中的內容逐一的複製到 String 中的字元陣列中。會建立一個新的字串物件,隨後修改的字元陣列不影響新建立的字串。

public String(char value[]) {
  this.value = Arrays.copyOf(value, value.length);
}

5)引數為 StringBuilder 或者 StringBuffer 型別

String(StringBuffer buffer)
Allocates a new string that contains the sequence of characters currently contained in the string buffer argument.
String(StringBuilder builder)
Allocates a new string that contains the sequence of characters currently contained in the string builder argument.

個人認為這種方式的構造方法用的比較少吧,如果是這兩種型別的,用 toString 方法的更方便一些。

StringBuilder sbb = new StringBuilder();
sbb.append("hello ").append("world");
String str1 = sbb.toString();

特別感謝以下博文:

Java 原始碼分析 —— String 的設計

Java 中 String 與 byte[] 的轉換

相關文章