char 是一个单一的字符,而 String 是一个字符的序列(也就是字符串)。

它们是两种完全不同的数据类型,在底层实现、用法和功能上都有巨大的差异。
核心区别速览表
| 特性 | char |
String |
|---|---|---|
| 本质 | 基本数据类型 | 引用数据类型 |
| 含义 | 表示一个单一的字符 | 表示一个零个或多个字符的序列 |
| 内存占用 | 2字节 (16位,使用 UTF-16 编码) | 可变,取决于字符串长度,对象头 + 字符数组 |
| 是否可变 | 不可变 (其值在初始化后不能改变) | 不可变 (Java 设计中,String 对象本身内容不可变) |
| 定义方式 | 用单引号 ,'A' |
用双引号 ,"Hello" |
| 默认值 | '\u0000' (空字符) |
null |
| 常用方法 | 无 (它是一个基本类型,没有方法) | 非常多,如 .length(), .charAt(), .substring(), .equals() 等 |
| 包装类 | Character |
无 (它本身就是类) |
详细解释
char - 字符
char 是 Java 的八种基本数据类型之一,它用来表示一个 Unicode 字符。
-
定义与赋值:必须使用单引号 。
char grade = 'A'; char ch = '中'; // Java 使用 Unicode,所以可以表示中文字符 char escape = '\n'; // 转义字符,代表换行
-
不可变性:
char是一个基本类型,它的值一旦被赋值,就不能再被改变,你只能创建一个新的char变量来存储新的值。
(图片来源网络,侵删)char ch = 'A'; // ch = 'B'; // 这是合法的,它把变量 ch 的引用指向了新的字符 'B' // 但 'A' 这个字符本身并没有被改变,只是 ch 变量现在存的是 'B' 了。
-
内存:在内存中只占 2 个字节,用于存储一个 UTF-16 编码的字符。
-
用途:通常用于处理单个字符的场景,比如遍历字符串时取出每个字符、表示状态码等。
String - 字符串
String 是一个在 Java 中非常特殊的引用数据类型(它是一个类),它用来表示一串字符。
-
定义与赋值:必须使用双引号 。
(图片来源网络,侵删)String name = "张三"; String greeting = "Hello, World!"; String emptyString = ""; // 空字符串,长度为 0
-
不可变性:这是
String最核心的特性,当一个String对象被创建后,它的内容不能被修改。String str = "Hello"; str = str + " World"; // 这看起来像是在修改 str,但实际上不是 // 底层发生了什么: // 1. "Hello" 和 " World" 被连接起来,创建了一个新的字符串对象 "Hello World"。 // 2. 变量 str 被重新指向了这个新的内存地址。 // 3. 原来的 "Hello" 对象如果没有被其他变量引用,就会被垃圾回收器回收。
这个特性使得
String线程安全,但也可能在频繁拼接字符串时带来性能问题(因此有了StringBuilder和StringBuffer)。 -
内存:
String对象在内存中的结构比较复杂,它包含一个对象头和一个指向char[]数组的引用,这个char[]数组才是真正存储字符的地方。 -
丰富的方法:
String类提供了大量非常有用的方法来操作字符串。String text = "Java Programming"; int length = text.length(); // 获取长度: 16 char firstChar = text.charAt(0); // 获取指定位置的字符: 'J' String sub = text.substring(5, 15); // 截取子串: "Programmin" boolean isEqual = text.equals("java programming"); // 比较内容: false String upper = text.toUpperCase(); // 转大写: "JAVA PROGRAMMING"
关键区别点深入解析
可变性的不同(核心)
char的“不可变”是指基本类型变量的值不能原地修改。String的“不可变”是指对象的内容不能被修改,任何修改操作都会返回一个新的String对象。
char 与 String 的转换
它们之间可以很方便地相互转换。
char 转 String
char ch = 'A';
// 方法1:最直接
String str1 = String.valueOf(ch); // 推荐
String str2 = "" + ch; // 常用,利用字符串连接
// 方法3:使用构造函数 (不推荐,因为会创建新的char[]数组)
String str3 = new String(new char[]{ch});
String 转 char
通常是从 String 中提取单个 char。
String str = "Hello"; // 获取指定索引的字符 char ch = str.charAt(1); // ch 的值是 'e' // 将整个字符串转换为 char 数组 char[] charArray = str.toCharArray(); // charArray 是 ['H', 'e', 'l', 'l', 'o']
性能考量
-
单个字符操作:如果只是处理单个字符,使用
char比使用String(String.valueOf('A'))更高效,因为它避免了创建对象的开销。 -
字符串拼接:在循环中进行大量字符串拼接时,直接使用 号会非常低效,因为每次拼接都会创建新对象,这时应该使用
StringBuilder或StringBuffer。// 低效方式 String result = ""; for (int i = 0; i < 1000; i++) { result += i; // 每次循环都创建一个新的 String 对象 } // 高效方式 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append(i); // 在同一个对象上进行操作 } String result = sb.toString();
总结与类比
你可以这样理解它们的关系:
char就像一块乐高积木:它是最小的、单一的、不可变的构建单元。String就像用乐高积木拼成的一辆模型车:它是由许多块(char)组成的复杂结构(对象),一旦拼好(创建),你就不能直接改变其中一块积木的颜色(不可变性),如果你想换一辆车,你必须重新拼一辆新的。
选择建议:
- 如果你的数据只是一个字符,比如一个字母、一个数字、一个符号,请使用
char。 - 如果你的数据是一串字符,比如一个单词、一句话、一段文本,请使用
String。
