在 Java 中,char 类型占用 2 个字节(16位)。

这是一个非常核心且重要的 Java 基础知识点,下面我们来详细解释为什么,以及它带来的影响。
核心原因:为了支持 Unicode 字符
Java 的设计初衷是“一次编写,到处运行”(Write Once, Run Anywhere),为了实现这个目标,Java 需要一种能统一表示世界上所有字符的编码方式,而不仅仅局限于 ASCII(美国信息交换标准代码)。
-
ASCII 的局限:
ASCII 使用 1 个字节(8位)来表示字符,只能表示 128 个字符(英文字母、数字、符号等),这对于英语世界足够了,但对于其他语言(如中文、法文、德文、日文等)则远远不够。
(图片来源网络,侵删) -
Unicode 的诞生:
- Unicode 是一个旨在收录世界上所有字符的字符集,它为每个字符分配一个唯一的数字,称为“码点”(Code Point)。
- 为了能表示超过 65,536 (2^16) 个字符,Unicode 最初的设计是使用 2 个字节(16位)来表示一个字符,这被称为 UTF-16 编码。
-
Java 的选择:
- Java 在设计时选择了 UTF-16 作为其
char类型的内部编码。 - 因为
char是 2 个字节(16位),所以它可以表示 Unicode 字符集中的 基本多语言平面,涵盖了绝大多数现代语言的字符。'A'->U+0041'中'->U+4E2D- ->
U+20AC
- Java 在设计时选择了 UTF-16 作为其
char 与 byte 的区别
| 特性 | char |
byte |
|---|---|---|
| 大小 | 2 字节 (16 bits) | 1 字节 (8 bits) |
| 用途 | 表示单个 Unicode 字符 | 表示原始的 8 位数据,常用于处理二进制流、网络传输或与底层系统交互。 |
| 范围 | '\u0000' (0) 到 '\uffff' (65,535) |
-128 到 127 |
- 你想存储一个字母、一个汉字、一个表情符号,用
char。 - 你想从文件或网络中读取原始的二进制数据,或者进行字节的运算,用
byte。
一个重要的特例:辅助平面字符
虽然 char 是 2 字节,但 Unicode 字符的数量已经远远超过了 65,536 个,这些超出基本多语言平面的字符被称为 辅助平面字符,例如某些生僻汉字、Emoji 表情(如 😂, 🚀)等。

这些字符的码点大于 U+FFFF,无法用一个 char 直接表示,Java 使用 代理对 来表示它们:
- 一个辅助平面字符由两个
char值组成:- 高位代理:范围在
\uD800到\uDBFF。 - 低位代理:范围在
\uDC00到\uDFFF。
- 高位代理:范围在
示例:
Emoji 表情 "火箭" 🚀 的码点是 U+1F680,它在 Java 中需要用两个 char 来表示:
// 🚀 的码点是 U+1F680
// 它被拆分为一个代理对
char highSurrogate = '\uD83D'; // 高位代理
char lowSurrogate = '\uDE80'; // 低位代理
// 这两个 char 必须成对出现,才能代表一个完整的字符
String rocket = new String(new char[]{highSurrogate, lowSurrogate});
System.out.println(rocket); // 输出: 🚀
如果你错误地只取其中一个 char,得到的是无效的“代字符”(surrogate code unit),无法正确显示。
代码示例
public class CharExample {
public static void main(String[] args) {
// char 的大小是 2 字节
System.out.println("Size of char in bytes: " + Character.BYTES); // 输出: 2
// char 的范围
System.out.println("Min value of char: " + (int)Character.MIN_VALUE); // 输出: 0
System.out.println("Max value of char: " + (int)Character.MAX_VALUE); // 输出: 65535
// 常见字符
char englishLetter = 'A';
char chineseChar = '中';
char emoji = '😂'; // 这个 Emoji 实际上是由两个 char 组成的代理对
System.out.println("English letter: " + englishLetter);
System.out.println("Chinese character: " + chineseChar);
System.out.println("Emoji: " + emoji);
// 检查一个 char 是否是代理对的一部分
System.out.println("Is '😂' a high surrogate? " + Character.isHighSurrogate(emoji)); // false
// 需要分别检查代理对中的两个 char
System.out.println("Is first part of '😂' a high surrogate? " + Character.isHighSurrogate("😂".charAt(0))); // true
}
}
- Java 中的
char固定占用 2 个字节(16位)。 - 这是为了支持 Unicode 字符集,使 Java 具有良好的国际化能力。
char用于表示单个 Unicode 字符,而byte用于表示原始的 8 位数据。- 对于超出
U+FFFF范围的辅助平面字符(如很多 Emoji),需要使用 两个char组成的代理对 来表示。
