包含特殊字符(例如?)的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?" 我更新了。 感谢您的相关评论:)

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

  1. PHP:计算字符串中汉字的个数、正确计算字符串的长度

    也许很多phper不知道,PHP内置的字符串长度函数strlen()无法正确处理中文字符串,它得到的只是字符串所占的字节数.对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UT ...

  2. java 月份缩写_关于java:如何将日期字符串解析为Date?

    本问题已经有最佳答案,请猛点这里访问. 如何将下面的日期字符串解析为Date对象? String target ="Thu Sep 28 20:29:30 JST 2000"; D ...

  3. java 字符串包_包java字符串

    Java核心技术卷I基础知识3.6.3 不可变字符串 3.6.3 不可变字符串 String类没有提供用于修改字符串的方法.如果希望将greeting的内容修改为"Help!",不 ...

  4. java考察代码_一段简单的关于字符串的 Java 代码竟考察了这么多东西

    下面的代码运行结果是什么?解释一下为什么会有这些差异. String s1 = "hello"; String s2 = s1 + ",world"; Stri ...

  5. ubuntu java classpath 设置_在Ubuntu中正确设置java classpath和java_home

    我有错误 Exception in thread"main" java.lang.NoClassDefFoundError: 当我尝试在Ubuntu上运行编译类时.我使用的是一个非 ...

  6. java字符串数组排序_在Java中对字符串数组进行排序

    允许用户使用字符串数组.他们可以向数组添加字符串,从数组中删除字符串,搜索数组中的字符串,最终他们将能够对数组进行排序.分类是搞砸我的原因.我尝试过几种不同的方法.第一种方法是将数组转换为ArrayL ...

  7. java 字符串连接_为什么 Java 要把字符串设计成不可变的

    String是Java中一个不可变的类,所以它一旦被实例化就无法被修改.不可变类的实例一旦创建,其成员变量的值就不能被修改.不可变类有很多优势.本文总结了为什么字符串被设计成不可变的.将涉及到内存.同 ...

  8. java的字符串池_翻译-Java字符串池

    正如名字所示:Java中字符串池存储在堆内存中.我们知道java中String是一个特殊的类,我们可以通过new 操作符或者使用双引号""创建一个String对象. Java里的字 ...

  9. java 字符串驻留_【Java中的字符串驻留】

    最近在工作的时候,一句再正常不过的代码String a = "hello" + "world";被改成了new StringBuilder().append(& ...

最新文章

  1. 常用工具之zabbix
  2. 重绘和回流----降低回流减少性能影响
  3. linux 文泉驿正黑字体,文泉驿字体系列打包下载-文泉驿字体下载-西西软件下载...
  4. R语言聚类算法的应用实例
  5. 阐明性问题生成 (Clarification Question Generation) 概览
  6. ysql怎么处理百分数? “%”
  7. 为什么每个请求都要有用户名密码呢,那不是每次都要查询一下了,token,表示这个用户已经验证通过了,在token有效期内,只需要判断token是否有效就可以了...
  8. Kubernetes是容器化微服务的圣杯么?
  9. thinkPHP的Excel插件
  10. Flink – submitJob
  11. 学习自动驾驶的路径是什么?这份技能图谱告诉你
  12. java dump可视化在线内存分析工具
  13. 【SpringBoot高级篇】springboot实现上传docdocx文件格式转pdf在线预览
  14. vi中跳到首行或尾行
  15. formula 返回list_如何在Hibernate / JPA中使用@Formula
  16. java禁止夏令时_在指定时区导入日期时间,忽略夏令时
  17. ym——android源代码大放送(实战开发必备)
  18. 单例模式、适配器模式
  19. 高级网格交易学习笔记
  20. 输出字符表情c语言,Objective-C读取十六进制代码并输出表情符号

热门文章

  1. WebFlux的WebClient框架
  2. vol.023 我有一只大黑狗
  3. 阿里云 socks5配置代理
  4. 55mW,10-bit,40-Ms/s奈奎斯特率CMOS ADC(一)
  5. 简单分享怎么开发自己的微信小程序_微信小程序快速制作步骤
  6. Flowable深入浅出-13 Flowable-BPMN操作流程之流程进展查看之流程图
  7. 全媒体运营师胡耀文教你:怎样让“用户留存分析模型”更好用
  8. cppcheck静态代码检测工具
  9. 手机短信被删除了怎么恢复
  10. mysql实现根据身份证号码计算出身日期和年龄