java字符串如何计算_关于Java:如何正确计算字符串字节?

包含特殊字符(例如?)的Java字符串在每个特殊字符中占用两个字节的大小,但是String length方法或使用从getBytes方法返回的字节数组获取其长度不会返回计数为两个字节的特殊字符。

如何正确计算字符串中的字节数?

例:

单词endere?o应该返回9而不是8。

当我运行System.out.println("endereo".getBytes().length);时,它显示" 9"。

@briarheart哪个Java版本?在Java 7中,我得到了八分。

@briarheart getBytes()使用平台默认编码,可能已经是UTF-8。请参阅:不同平台上的平台默认字符集?

我正在使用Java8。我想" utf-8"是任何版本的Java的默认编码,除非显式覆盖此行为。

定义特殊字符。是什么让您认为它需要两个字节的大小?哪里?您是指char[]中支持String的意思吗?单词endereo应该使我返回9而不是8。为什么?为什么不32?

@briarheart UTF-8不是任何Java版本的默认编码。默认编码通常由操作系统定义,在Linux上通常为UTF-8,但在Windows上很少。

长度在很大程度上取决于编码,例如对于endereo及其ISO-8859-1:8,UTF-8:9,EUC-JP:10,UTF-16BE:16,UTF-32:32

@安德烈亚斯是的,你是对的。即使未指定,我也会看到值为" UTF-8"的" file.encoding"属性。" UTF-8"的显式后备仅存在于java.nio.charset.Charset类的代码中。

我没有得到正确的长度,因为我的默认编码是ISO-8859-1。

同样,定义长度。 String#length()方法具有非常具体的定义。

究竟是哪个定义?

所有Java字符串内部都使用两字节字符。

The word endere?o should return me length 9 instead of 8.

如果您希望长度为8个字符的"endere?o"字符串的大小为9个字节:7个ASCII字符和1个非ASCII字符,那么我想您要使用UTF-8字符集ASCII表中包含的字符为1个字节,其他字符为1个字节。

but String length method or getting the length of it with the byte

array returned from getBytes method doesn't return special chars

counted as two bytes.

String length()方法不能回答以下问题:使用了多少个字节?但是回答:"其中包含多少个" UTF-16代码单元"或更简单的char?"

String length() Javadoc:

Returns the length of this string. The length is equal to the number

of Unicode code units in the string.

没有参数的byte[] getBytes()方法将String编码为字节数组。您可以使用返回数组的length属性来了解编码的String使用了多少字节,但是结果将取决于编码期间使用的字符集。

但是byte[] getBytes()方法不允许指定字符集:它使用平台的默认字符集。

因此,如果底层操作系统默认情况下使用的字符集不是您要用来以字节编码字符串的字符集,则使用它可能无法获得预期的结果。

此外,根据部署应用程序的平台,以字节为单位的字符串编码方式可能会发生变化。这可能是不希望的。

最后,如果无法将字符串编码为默认字符集,则该行为未指定。

因此,应非常谨慎地使用此方法,或者完全不要使用。

byte[] getBytes() Javadoc:

Encodes this String into a sequence of bytes using the platform's

default charset, storing the result into a new byte array.

The behavior of this method when this string cannot be encoded in the

default charset is unspecified. The java.nio.charset.CharsetEncoder

class should be used when more control over the encoding process is

required.

在您的String示例"endere?o"中,如果getBytes()返回一个大小为8而不是9的数组,则意味着您的操作系统默认不使用UTF-8,而是一个字符集使用1字节固定宽度的字符集,例如ISO 8859-1及其派生字符集(例如,基于Windows OS的windows-1252)。

要了解运行该应用程序的当前Java虚拟机的默认字符集,可以使用以下实用程序方法:Charset defaultCharset = Charset.defaultCharset()。

byte[] getBytes()方法带有另外两个非常有用的重载:

byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException

byte[] java.lang.String.getBytes(Charset charset)

与没有参数的getBytes()方法相反,这些方法允许指定在字节编码期间使用的字符集。

byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException Javadoc:

Encodes this String into a sequence of bytes using the named charset,

storing the result into a new byte array.

The behavior of this method when this string cannot be encoded in the

given charset is unspecified. The java.nio.charset.CharsetEncoder

class should be used when more control over the encoding process is

required.

byte[] java.lang.String.getBytes(Charset charset) Javadoc:

Encodes this String into a sequence of bytes using the given charset,

storing the result into a new byte array.

This method always replaces malformed-input and unmappable-character

sequences with this charset's default replacement byte array. The

java.nio.charset.CharsetEncoder class should be used when more control

over the encoding process is required.

您可以使用一个或另一个(虽然它们之间有一些复杂性)将您的String编码为带有UTF-8或任何其他字符集的字节数组,然后获取此特定字符集的大小。

例如,要通过使用getBytes(String charsetName)获得UTF-8编码字节数组,可以执行以下操作:

String yourString ="endere?o";

byte[] bytes = yourString.getBytes("UTF-8");

int sizeInBytes = bytes.length;

并且您将获得9字节的长度,如您所愿。

这是一个更全面的示例,其中显示了默认编码,使用默认字符集平台UTF-8和UTF-16的字节编码:

public static void main(String[] args) throws UnsupportedEncodingException {

// default charset

Charset defaultCharset = Charset.defaultCharset();

System.out.println("default charset =" + defaultCharset);

// String sample

String yourString ="endere?o";

//  getBytes() with default platform encoding

System.out.println("getBytes() with default charset, size =" + yourString.getBytes().length + System.lineSeparator());

// getBytes() with specific charset UTF-8

System.out.println("getBytes("UTF-8"), size =" + yourString.getBytes("UTF-8").length);

System.out.println("getBytes(StandardCharsets.UTF_8), size =" + yourString.getBytes(StandardCharsets.UTF_8).length + System.lineSeparator());

// getBytes() with specific charset UTF-16

System.out.println("getBytes("UTF-16"), size =" + yourString.getBytes("UTF-16").length);

System.out.println("getBytes(StandardCharsets.UTF_16), size =" + yourString.getBytes(StandardCharsets.UTF_16).length);

}

基于Windows操作系统的计算机上的输出:

default charset = windows-1252

getBytes() with default charset, size = 8

getBytes("UTF-8"), size = 9

getBytes(StandardCharsets.UTF_8), size = 9

getBytes("UTF-16"), size = 18

getBytes(StandardCharsets.UTF_16), size = 18

"字符串length()方法不能回答以下问题:使用了多少个字节?但是回答:"包含多少个字符?"不,它返回字符串中UTF-16代码单元的数量。可以有多个代码 每个代码点的单位,每个"字素簇"可以有多个代码点(大多数用户会认为一个字符)。

@plugwash从技术上讲,是的,您是正确的。 我想我太庸俗了。 我会更具体一些:"包含多少char?" 我更新了。 感谢您的相关评论:)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值