## 字符串
在底层上跟C#类似,每个字符串的实例都不可修改。当修改字符串变量时,是将变量指向新的字符串实例,而不是修改原本的实例。Java中也有字符串池机制。
**注意:使用 `==` 运算符比较字符串时,跟C#有根本上的差别。在Java中这里的 `==` 操作符相当于C#中的 `Object.ReferenceEquals(strA, strB)` 方法。**
Java中比较字符串要使用 `equals` 方法,忽略大小写比较时使用 `equalsIgnoreCase` 方法。
## 码点和代码单元
Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。`length` 方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。
```java
String str = "Hello, \uD842\uDFB7!";
System.out.println(str); // Hello, 𠮷!
int n = str.length();
System.out.println(n); // 10
int cpCount = str.codePointCount(0, str.length());
System.out.println(cpCount); // 9
```
这里跟C#有相当大的不同,看一下下面的C#示例代码。
```csharp
string str = "Hello, 𠮷!";
Console.WriteLine(str); // Hello, ??!
Console.WriteLine(str.Length); // 10
Console.WriteLine(Encoding.UTF8.GetByteCount(str)); // 12
Console.WriteLine(Encoding.GetEncoding("GB2312").GetByteCount(str)); // 10
Console.ReadLine();
```
字符串 `"Hello, 𠮷!"` 中英文字母、标点符号和空格总共占了8个字节,剩下的一个汉字(**𠮷**)就比较特殊了。将这个字复制到Java的IDE中会自动变成两个Unicode码(`\uD842\uDFB7`),可以看出它占了4个字节。
- Java中的 `length` 方法和 C#中的 `Length` 属性的值是一致的,返回的都是代码单元的数量。
- Java中可以通过 `codePointCount` 方法获取码点的数量。
- C#中通过 `Encoding.UTF8.GetByteCount` 方法获取的是字节数, `Encoding.GetEncoding("GB2312").GetByteCount` 方法获取的也是代码单元数量,都不是码点数量。
- C#中需要使用 [StringInfo](https://docs.microsoft.com/en-us/dotnet/api/system.globalization.stringinfo?view=netframework-4.7.1 "StringInfo") 类获取码点数。
> Internally, the methods of the StringInfo class call the methods of the CharUnicodeInfo class to determine character categories. Starting with the .NET Framework 4.6.2, character classification is based on [The Unicode Standard, Version 8.0.0](http://unicode.org/versions/Unicode8.0.0 "The Unicode Standard, Version 8.0.0"). For the .NET Framework 4 through the .NET Framework 4.6.1, it is based on [The Unicode Standard, Version 6.3.0](http://www.unicode.org/versions/Unicode6.3.0/ "The Unicode Standard, Version 6.3.0").
示例代码:
```cs
StringInfo si = new StringInfo(str);
Console.WriteLine(si.String); // Hello, ??!
Console.WriteLine(si.LengthInTextElements); // 9
```