详解Java语言中一个字符占几个字节?

作者:du_xian_sheng 时间:2023-08-26 11:45:40 

题主要区分清楚内码(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编码)而做的取舍。

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

如果你说的“字符”就是指 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 -Dfile.encoding=GBK Main这时,你再执行不带参数的 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 中运行你的程序时,会加上上述的 -Dfile.encoding=UTF-8 参数,这时,即便你在 Windows 下,缺省编码也是 UTF-8,而不是 GBK。

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

以上所述是小编给大家介绍的Java语言中一个字符占几个字节详解整合网站的支持!

来源:https://blog.csdn.net/h12kjgj/article/details/73496949

标签:java,字符,字节
0
投稿

猜你喜欢

  • 获取Android签名证书的公钥和私钥的简单实例

    2022-10-02 22:20:13
  • springboot项目如何防止XSS攻击

    2021-10-17 10:03:02
  • C#中线程同步对象的方法分析

    2021-06-06 05:43:46
  • JavaWeb实现文件上传与下载的方法

    2023-12-23 04:42:56
  • Java实现的对称加密算法AES定义与用法详解

    2021-10-16 22:16:05
  • SpringBoot使用validation-api实现参数校验的示例

    2022-12-02 14:33:40
  • Java类加载机制实现流程及原理详解

    2022-05-26 02:53:24
  • C#结合AForge实现摄像头录像

    2021-06-28 03:53:51
  • 如何写好一个Spring组件的实现步骤

    2023-01-08 20:24:12
  • Android自定义控件基本原理详解(一)

    2022-05-02 12:29:32
  • Java 随机生成验证码(支持大小写字母、数字、随机字体)的实例

    2023-11-25 00:35:38
  • SpringBoot JPA使用配置过程详解

    2022-12-03 15:31:33
  • Java使用Freemarker页面静态化生成的实现

    2022-07-24 08:48:42
  • Java DatabaseMetaData用法案例详解

    2023-08-18 19:08:42
  • java中如何执行xshell命令

    2021-10-06 16:22:18
  • idea插件之mybatis log plugin控制台sql的问题

    2023-05-14 06:45:32
  • Unity实现物体左右移动效果

    2021-12-17 15:52:31
  • android studio 项目 :UI设计高精度实现简单计算器

    2022-07-14 02:09:29
  • Java控制台实现猜拳游戏

    2022-12-15 09:54:46
  • C#用Activex实现Web客户端读取RFID功能的代码

    2021-10-28 21:07:36
  • asp之家 软件编程 m.aspxhome.com