java一个字符几个字节_Java 语言中一个字符占几个字节?

java一个字符几个字节_Java 语言中一个字符占几个字节?Java中理论说是一个字符(汉字字母)占用两个字节。但是在UTF-8的时候newString(“字”).getBytes().length返回的是3表示3个字节作者:RednaxelaFX链接:https://www.zhihu.com/question/27562173/answer/37188642来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。题主…

大家好,又见面了,我是你们的朋友全栈君。

Java中理论说是一个字符(汉字 字母)占用两个字节。

但是在UTF-8的时候 new String(“字”).getBytes().length 返回的是3 表示3个字节

作者:RednaxelaFX

链接:https://www.zhihu.com/question/27562173/answer/37188642

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题主要区分清楚内码(internal encoding)和外码(external encoding)就好了。内码是程序内部使用的字符编码,特别是某种语言实现其char或String类型在内存里用的内部编码;外码是程序与外部交互时外部使用的字符编码。“外部”相对“内部”而言;不是char或String在内存里用的内部编码的地方都可以认为是“外部”。例如,外部可以是序列化之后的char或String,或者外部的文件、命令行参数之类的。Java语言规范规定,Java的char类型是UTF-16的code unit,也就是一定是16位(2字节);char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1).然后字符串是UTF-16 code unit的序列:The Java programming language represents text in sequences of 16-bit code units, using the UTF-16 encoding.这样,Java规定了字符的内码要用UTF-16编码。或者至少要让用户无法感知到String内部采用了非UTF-16的编码。“感知”可以是多方面的,例如随机访问某个下标的code unit(String.charAt())应该是O(1)操作,这只有使用UTF-16或者别的“定长”编码才可以做到。注意我这里说的“定长”特指code unit定长,而不是说code point定长。String.getBytes()是一个用于将String的内码转换为指定的外码的方法。无参数版使用平台的默认编码作为外码,有参数版使用参数指定的编码作为外码;将String的内容用外码编码好,结果放在一个新byte[]返回。题主的例子里,显然外码是UTF-8,那么调用了String.getBytes()之后得到的byte[]只能表明该外码的性质,而无法碰触到String内码的任何特质。另举一例:Java标准库实现的对char与String的序列化规定使用UTF-8作为外码。Java的Class文件中的字符串常量与符号名字也都规定用UTF-8编码。这大概是当时设计者为了平衡运行时的时间效率(采用定长编码的UTF-16)与外部存储的空间效率(采用变长的UTF-8编码)而做的取舍。题外话1:可惜UTF-16在Java设计之初还是真的定长编码,后来Unicode涵盖的字符变多了之后UTF-16变成了坑爹的变长编码(一个完整的“字符”是一个code point;一个code point可以对应1到2个code unit;一个code unit是16位),Java也只好跟进。为了实现UTF-16的变长编码语义,Java规定char仍然只能是一个16位的code point,也就是说Java的char类型不一定能表示一个UTF-16的“字符”——只有只需1个code unit的code point才可以完整的存在char里。但String作为char的序列,可以包含由两个code unit组成的“surrogate pair”来表示需要2个code unit表示的UTF-16 code point。为此Java的标准库新加了一套用于访问code point的API,而这套API就表现出了UTF-16的变长特性。题外话2:前面我说Java的内码时说得比较松,留下了“不总是使用UTF-16作为内码,但是用户无法感知区别”的余地。在Sun JDK6中有一个“压缩字符串”(-XX:+UseCompressedString)的功能。启用后,String内部存储字符串内容可能用byte[],也可能用char[];当整个字符串所有字符都在ASCII编码范围内时,就使用byte[](ASCII序列)来存储,此时字符串就处于“压缩”状态;反之,只要有任何一个字符超出了ASCII的编码范围,就退回到用char[](UTF-16序列)来存储。ASCII编码也是一种定长编码,而且其涵盖的字符是UTF-16的真子集;用户在对一个“压缩”的字符串访问其内容时(例如String.charAt()),只需对ASCII字符做无符号扩展就可以得到对应的UTF-16 code unit。这样用户也就无法感知到Java String的内码不是UTF-16的情况。Sun JDK6对“压缩字符串”的实现不够理想,实现太复杂而效果未如预期的好,所以没有包含在OpenJDK6、Oracle JDK7/OpenJDK7里。现在Oracle在重新审视“压缩字符串”功能,有可能在JDK9重新实现出来。题外话3:同样规定使用UTF-16作为内码的JavaScript语言,其实现广泛应用了“压缩字符串”的思想。现在主流的JavaScript引擎都会尽可能用ASCII内码的字符串,不过用户能接触的API只能看到UTF-16 code unit。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/153107.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • DrawerLayout详解「建议收藏」

    DrawerLayout详解「建议收藏」drawerLayout是SupportLibrary包中实现了侧滑菜单效果的控件,可以说drawerLayout是因为第三方控件如MenuDrawer等的出现之后,google借鉴而出现的产物。drawerLayout分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(drawerLayout自身特性),主内容区的内容可以随着菜单的点击而变化(这需要使用者自己实现)。

    2022年6月16日
    30
  • 用斐波那契数列来说明递归和迭代的区别「建议收藏」

    用斐波那契数列来说明递归和迭代的区别「建议收藏」递归:自己调用自己迭代:反复替换的意思递归与迭代都是基于控制结构:迭代用重复结构,而递归用选择结构。递归与迭代都涉及重复:迭代显式使用重复结构,而递归通过重复函数调用实现重复。递归与迭代都涉及终止测试:迭代在循环条件失败时终止,递归在遇到基本情况时终止。使用计数器控制重复的迭代和递归都逐渐到达终止点:迭代一直修改计数器,直到计数器值使循环条件失败;递归不断产生最初问题的简化副本

    2022年6月3日
    41
  • oracle 行列转换 pivot

    oracle 行列转换 pivot

    2021年8月31日
    53
  • poetry下载_k8s安装工具

    poetry下载_k8s安装工具介绍Poetry是Python中的依赖管理和打包工具,当然它也可以配置虚拟环境。它允许您声明项目所依赖的库,并为您管理(安装/更新)它们。之前一直使用virtualenvwrapper管理虚拟

    2022年8月7日
    4
  • 光栅投影中Gamma校正

    光栅投影中Gamma校正学习郑东亮达飞鹏《提高数字光栅投影测量系统精度的gamma校正技术》一文后,对其中的关键技术进行了解析。摄像机获得的实际灰度图像:其中是整个系统的gamma值,是预编码值(需要根据实验进行选择),是幅度调制(保证归一化),是背景光强,和是由系统确定的值(需要通过投射不同的灰度图进行解算)。gamma校正的目的:选择一个合适的预编码值,使得,从而使系统的gamma失真得以消除或者减…

    2022年6月22日
    22
  • Java学习路线图(完整详细2021版)

    Java学习路线图(完整详细2021版)作为一个男人我感觉必须得做点什么来证明一下自己,现在我又回来了,准备把自己的节操准备补一下 另外给各位未来的Java程序员说一句,别的我不清楚,学习编程请从一而终 咱们学习编程就挺难的,有这些先驱者来带领咱们学习,咱们应该感激,而且最重要的事跟着你选定的一家一直学下去 因为每家学校的学习大纲都是不一样的,但是程序员其实都是一样的,这句话你细品!仔细的品! 我不希望你忙忙碌碌的整理那么多东西,挑肥拣瘦的,最后自己学的东西还是缺失的,要不就…

    2022年5月17日
    85

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号