Java语言中一个字符占几个字节?「建议收藏」

Java语言中一个字符占几个字节?「建议收藏」要区分清楚内码(internalencoding)和外码(externalencoding)就好了。内码是程序内部使用的字符编码,特别是某种语言实现其char或String类型在内存里用的内部编码;外码是程序与外部交互时外部使用的字符编码。“外部”相对“内部”而言;不是char或String在内存里用的内部编码的地方都可以认为是“外部”。例如,外部可以是序列化之后的char或String…

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

要区分清楚内码(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的编码。

 

另举一例:
Java标准库实现的对char与String的序列化规定使用UTF-8作为外码。Java的Class文件中的字符串常量与符号名字也都规定用UTF-8编码。这大概是当时设计者为了平衡运行时的时间效率(采用定长编码的UTF-16)与外部存储的空间效率(采用变长的UTF-8编码)而做的取舍。
作者:国栋
链接:https://www.zhihu.com/question/27562173/answer/76208352
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

首先,你所谓的“字符”具体指什么呢?

如果你说的“字符”就是指 Java 中的 char,那好,那它就是 16 位,2 字节。

如果你说的“字符”是指我们用眼睛看到的那些“抽象的字符”,那么,谈论它占几个字节是没有意义的。

具体地讲,脱离具体的编码谈某个字符占几个字节是没有意义的

就好比有一个抽象的整数“42”,你说它占几个字节?这得具体看你是用 byte,short,int,还是 long 来存它。用 byte 存就占一字节,用 short 存就占两字节,int 通常是四字节,long 通常八字节。当然,如果你用 byte,受限于它有限的位数,有些数它是存不了的,比如 256 就无法放在一个 byte 里了。

字符是同样的道理,如果你想谈“占几个字节”,就要先把编码说清楚。

同一个字符在不同的编码下可能占不同的字节

就以你举的“
”字为例,“
”在 GBK 编码下占 2 字节,在 UTF-16 编码下也占 2 字节,在 UTF-8 编码下占 3 字节,在 UTF-32 编码下占 4 字节。

不同的字符在同一个编码下也可能占不同的字节


”在 UTF-8 编码下占3字节,而“
A”在 UTF-8 编码下占 1 字节。(因为 UTF-8 是
变长编码)

而 Java 中的 char 本质上是 UTF-16 编码。而 UTF-16 实际上也是一个变长编码(2 字节或 4字节)。

如果一个抽象的字符在 UTF-16 编码下占 4 字节,显然它是不能放到 char 中的。换言之, char 中只能放 UTF-16 编码下只占 2 字节的那些字符。

而 getBytes 实际是做编码转换,你应该显式传入一个参数来指定编码,否则它会使用缺省编码来转换。

你说“ new String(“字”).getBytes().length 返回的是3 ”,这说明缺省编码是 UTF-8.如果你显式地传入一个参数,比如这样“ new String(“字”).getBytes(”
GBK“).length ”,那么返回就是 2.

你可以在启动 JVM 时设置一个缺省编码,

假设你的类叫 Main,那么在命令行中用 java 执行这个类时可以通过 file.encoding 参数设置一个缺省编码。比如这样:java -D
file.encoding=
GBKMain这时,你再执行不带参数的 getBytes() 方法时,new String(“字”).getBytes().length 返回的就是 2 了,因为现在缺省编码变成 GBK 了。当然,如果这时你显式地指定编码,new String(“字”).getBytes(”
UTF-8“).length 返回的则依旧是 3.

否则,会使用所在操作系统环境下的缺省编码。

通常,Windows 系统下是 GBK,Linux 和 Mac 是 UTF-8.但有一点要注意,在 Windows 下使用 IDE 来运行时,比如 Eclipse,如果你的工程的缺省编码是 UTF-8,在 IDE 中运行你的程序时,会加上上述的 -D
file.encoding=
UTF-8 参数,这时,即便你在 Windows 下,缺省编码也是 UTF-8,而不是 GBK。

由于受启动参数及所在操作系统环境的影响,不带参数的 getBytes 方法通常是不建议使用的,最好是显式地指定参数以此获得稳定的预期行为。

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

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

(0)
上一篇 2022年6月26日 下午4:46
下一篇 2022年6月26日 下午5:00


相关推荐

  • 使用vue开发移动端app 暂停更新中

    使用vue开发移动端app 暂停更新中使用 vue 开发移动端 app 开发前准备 Vue 移动端框架参考资料 vuejs2 0 高级实战全网稀缺音乐 WebAPPVue2 0 开发企业级移动音乐 APP 导学 附 github 源码网易云音乐接口 vue 全家桶开发一款移动端音乐 webAppVue 项目打包成移动端 APP 从零开始搭建 vue 移动端项目到上线

    2026年3月18日
    2
  • 基于Redis实现DelayQueue延迟队列设计方案(附源码)「建议收藏」

    基于Redis实现DelayQueue延迟队列设计方案(附源码)「建议收藏」应用场景创建订单10分钟之后自动支付叫预约单专车出行前30分钟发送短信提示订单超时取消…等等…实现方式最简单的方式,定时扫表;例如每分钟扫表一次十分钟之后未支付的订单进行主动支付;优点:简单缺点:每分钟全局扫表,浪费资源,有一分钟延迟使用RabbitMq实现RabbitMq实现延迟队列优点:开源,现成的稳定的实现方案;缺点:RabbitMq是一个…

    2022年5月3日
    74
  • FVWM简明使用指南

    FVWM简明使用指南http://minus273.eu/mirrors/2001315450/fvwm_frame.html简明使用指南FvwmisawindowmanagerforX11.Itisdesignedtominimizememoryconsumption,providea3Dlooktowindowframes,andavirtual

    2022年10月4日
    6
  • ARP–利用arpspoof和driftnet工具进行arp欺骗

    ARP–利用arpspoof和driftnet工具进行arp欺骗实验目的:1.了解ARP欺骗的原理。2.对ARP欺骗进行进一步的认识并提出防范措施。3.掌握熟悉arpspoof和driftnet的使用方法。任务与要求:1、利用arpspoof进行ARP断网攻击2.利用arpspoof工具和driftnet工具进行ARP欺骗原理:ARP(AddressResolutionProtocol)是地址解析协议,是一种将IP地址转化成物理地址的协议。从IP地址到物理地址的映射有两种方式:表格方式和非表格方式。ARP具体说来就…

    2026年4月15日
    4
  • windows 批处理 注释_vim批量注释

    windows 批处理 注释_vim批量注释一、Windows批处理添加注释使用::即可注释文字如图所示

    2025年5月29日
    6
  • html标题栏显示文字居中,让标题栏文字居中

    html标题栏显示文字居中,让标题栏文字居中下载本文示例代码 p gt 添加以下模块 PublicSubCen frmAsForm DimSpcFAsInt

    2026年3月26日
    2

发表回复

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

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