Skip to content

C# 和 Java 中字符串的异同

🏷️ C# Java

字符串

在底层上跟 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 类获取码点数。

    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. For the .NET Framework 4 through the .NET Framework 4.6.1, it is based on The Unicode Standard, Version 6.3.0.

    示例代码:

    cs
    StringInfo si = new StringInfo(str);
    Console.WriteLine(si.String); // Hello, ??!
    Console.WriteLine(si.LengthInTextElements); // 9