Java中字符串的字节数

Gre*_*en 156 java string

在Java中,如果我有一个String x,我该如何计算该字符串中的字节数?

And*_*yle 270

字符串是字符列表(即代码点).表示字符串所用的字节数完全取决于用于将其转换为字节的编码.

也就是说,您可以将字符串转换为字节数组,然后查看其大小,如下所示:

// The input string for this test
final String string = "Hello World";

// Check length, in characters
System.out.println(string.length()); // prints "11"

// Check encoded sizes
final byte[] utf8Bytes = string.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "11"

final byte[] utf16Bytes= string.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "24"

final byte[] utf32Bytes = string.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "44"

final byte[] isoBytes = string.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "11"

final byte[] winBytes = string.getBytes("CP1252");
System.out.println(winBytes.length); // prints "11"
Run Code Online (Sandbox Code Playgroud)

所以你看,即使一个简单的"ASCII"字符串在其表示中也可以有不同的字节数,这取决于使用哪种编码.使用您感兴趣的任何字符集作为您的案例getBytes().并且不要陷入假设UTF-8将每个字符表示为单个字节的陷阱,因为这也不是真的:

final String interesting = "\uF93D\uF936\uF949\uF942"; // Chinese ideograms

// Check length, in characters
System.out.println(interesting.length()); // prints "4"

// Check encoded sizes
final byte[] utf8Bytes = interesting.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "12"

final byte[] utf16Bytes= interesting.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "10"

final byte[] utf32Bytes = interesting.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "16"

final byte[] isoBytes = interesting.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "4" (probably encoded "????")

final byte[] winBytes = interesting.getBytes("CP1252");
System.out.println(winBytes.length); // prints "4" (probably encoded "????")
Run Code Online (Sandbox Code Playgroud)

(请注意,如果您不提供字符集参数,则使用平台的默认字符集.这在某些上下文中可能很有用,但通常您应该避免依赖于默认值,并且在编码/时始终使用显式字符集解码是必需的.)

  • 你做了一个有力的解释.谢谢 (6认同)
  • @Green Ash字节数组的长度 - getBytes() - 和x.length可以相等但不保证是这样.如果所有字符都由每个字节表示,则它将是相等的.对于每个字符(或更少)使用单个字节的字符编码(例如ISO-8859-1),这始终适用.UTF-8使用1或2个字节,因此它取决于字符串中的确切字符.然后是字符编码,每个字符总是使用两个字节. (4认同)

roo*_*beh 57

如果您使用64位引用运行:

sizeof(string) = 
8 + // object header used by the VM
8 + // 64-bit reference to char array (value)
8 + string.length() * 2 + // character array itself (object header + 16-bit chars)
4 + // offset integer
4 + // count integer
4 + // cached hash code
Run Code Online (Sandbox Code Playgroud)

换一种说法:

sizeof(string) = 36 + string.length() * 2
Run Code Online (Sandbox Code Playgroud)

在具有压缩OOP(-XX:+ UseCompressedOops)的32位VM或64位VM上,引用为4个字节.所以总数将是:

sizeof(string) = 32 + string.length() * 2
Run Code Online (Sandbox Code Playgroud)

这不考虑对字符串对象的引用.

  • 我假设问题是关于String对象在内存中分配的字节数.如果问题是序列化字符串所需的字节数,正如其他人所指出的那样,它取决于所使用的编码. (4认同)
  • 你的答案来源?谢谢 (2认同)

fin*_*nnw 18

迂腐的答案(虽然不一定是最有用的答案,取决于你想对结果做什么)是:

string.length() * 2
Run Code Online (Sandbox Code Playgroud)

Java字符串以物理方式存储在UTF-16BE编码中,每个代码单元使用2个字节,并String.length()以UTF-16代码单位测量长度,因此这相当于:

final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);
Run Code Online (Sandbox Code Playgroud)

这将告诉你内部char数组的大小,以字节为单位.

注意:"UTF-16"将给出不同的结果,"UTF-16BE"因为前一个编码将插入BOM,向数组的长度添加2个字节.


Bor*_*vić 15

根据如何在Java中将字符串转换为UTF8字节数组:

String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);
Run Code Online (Sandbox Code Playgroud)

  • 要清楚这是输出: test.java:11: unreported exception java.io.UnsupportedEncodingException; 必须被捕获或声明被抛出 byte[] b = s.getBytes("UTF-8"); ^ 1 错误 处理完成。 (2认同)
  • @Green,尝试:`s.getBytes(Charset.forName(“ UTF-8”))`。 (2认同)

And*_*s_D 9

String的实例分配一定量的在存储器的字节.也许你正在寻找sizeof("Hello World")能够返回数据结构本身分配的字节数的东西?

在Java中,通常不需要sizeof函数,因为我们从不分配内存来存储数据结构.我们可以查看String.java文件进行粗略估计,我们看到一些'int',一些引用和一个char[].在Java语言规范定义,一个char范围为0〜65535,所以两个字节是足以保持一个单个字符在存储器中.但是JVM不必在2个字节中存储一个char,它只需要保证,实现char可以保存定义范围的值.

所以sizeofJava中没有任何意义.但是,假设我们有一个大的String并且一个char分配两个字节,那么String对象的内存占用量至少2 * str.length()以字节为单位.


And*_*anu 5

有一个名为getBytes()的方法.明智地使用它.

  • 明智地=不要使用没有字符集参数的那个. (16认同)
  • getBytes 还将创建和复制字节数组,因此如果您正在谈论长字符串,则此操作可能会变得昂贵。 (2认同)

ant*_*ant 5

尝试这个 :

Bytes.toBytes(x).length
Run Code Online (Sandbox Code Playgroud)

假设您之前声明并初始化了 x

  • 这是标准 Java 库的一部分吗?我找不到 `Bytes` 类。 (4认同)