杰瑞科技汇

java char和string

核心区别(一句话总结)

  • char单个字符,它是 Java 的基本数据类型,用单引号 表示。
  • String字符串,它是 Java 的一个(位于 java.lang 包),表示一个字符序列,用双引号 表示。

char - 字符类型

char 是 Java 中唯一一个用于表示 Unicode 字符的类型。

java char和string-图1
(图片来源网络,侵删)

1 基本特性

  • 类型:基本数据类型 (Primitive Data Type)。
  • 大小:在 Java 中,char16 位(2 字节)无符号整数,因此可以表示 Unicode 字符集中的所有字符(从 \u0000\uffff)。
  • 表示:使用单引号 括起来。'A', '1', '中', '\n'
  • 默认值'\u0000' (即 NUL 字符)。

2 如何声明和赋值

char ch1 = 'A';          // 一个英文字母
char ch2 = '中';          // 一个中文字符
char ch3 = '1';          // 一个数字字符
char ch4 = '\n';         // 一个转义字符(换行)
char ch5 = '\u4e2d';     // 一个 Unicode 转义序列,代表 '中'

3 char 的本质

char 本质上是一个无符号的 16 位整数,你可以直接给它赋一个整数值,这个值会被当作 Unicode 码点来解析。

char ch6 = 65;  // 65 是 'A' 的 Unicode 码点
System.out.println(ch6); // 输出 A
char ch7 = '\u0041'; // \u0041 是 'A' 的十六进制 Unicode 码点
System.out.println(ch7); // 输出 A

4 常用操作

char 的操作通常是比较和算术运算(因为其本质是整数)。

char a = 'a';
char b = 'b';
// 比较字符
if (a < b) {
    System.out.println("'a' 的 Unicode 码点小于 'b'"); // 输出
}
// 字符算术运算(基于其 Unicode 码点)
char nextChar = (char) (a + 1); // 'a' + 1 = 98, 即 'b'
System.out.println(nextChar); // 输出 b

String - 字符串类

String 在 Java 中是一个非常特殊的类,它被广泛使用并且有一些独特的性质。

1 基本特性

  • 类型:引用数据类型 (Reference Data Type)。
  • 本质:它是一个不可变的字符序列,这意味着一旦一个 String 对象被创建,它的内容就不能被改变。
  • 表示:使用双引号 括起来。"Hello", "你好", "123"`。
  • 默认值null

2 不可变性 的含义

这是 String 最重要的特性,当你看起来像是在修改一个字符串时,JVM 是在内存中创建了一个新的 String 对象,而原来的对象保持不变。

java char和string-图2
(图片来源网络,侵删)
String s1 = "hello";
String s2 = s1; // s2 和 s1 引用同一个对象
// s1.concat(" world") 看起来像是修改了 s1
// 但实际上,它返回了一个新的 String 对象 "hello world"
// s1 本身并没有被改变
s1 = s1.concat(" world"); 
System.out.println(s1); // 输出 hello world
System.out.println(s2); // 输出 hello (s2 仍然指向原来的对象)

不可变性的好处

  • 线程安全不能被改变,所以在多线程环境下使用 String 是安全的,无需额外的同步机制。
  • 可以被安全地共享:可以放心地在多个地方传递同一个 String 对象,不用担心它会被意外修改。
  • 哈码缓存不变,String 对象的 hashCode() 值在创建后就不会改变,这使得 String 非常适合作为 HashMap 等哈希集合的键。

3 如何声明和创建

// 方式1:使用字面量(最常用)
// Java 会对字符串字面量进行“字符串池”(String Pool)优化
String str1 = "Hello, World!";
// 方式2:使用 new 关键字(不推荐,除非有特殊需求)
// 这会强制在堆上创建一个新的 String 对象,即使内容相同
String str2 = new String("Hello, World!");

4 String vs char[]

String 内部就是使用一个 char[] 数组来存储字符的。String 封装了这个数组,并提供了大量操作方法,使其功能更强大、更安全。

  • char[] 是一个可变的字符数组。
  • String 是一个不可变的字符序列。
// char[] 的可变性
char[] chars = {'H', 'e', 'l', 'l', 'o'};
chars[0] = 'h'; // 合法,修改了第一个字符
System.out.println(chars); // 输出 [h, e, l, l, o]
// String 的不可变性
String str = "Hello";
// str[0] = 'h'; // 编译错误!String 没有 setCharAt() 方法

5 常用方法

String 类提供了非常丰富的方法来操作字符串。

String text = "  Hello Java  ";
// 获取长度
System.out.println(text.length()); // 输出 13
// 连接字符串
String newStr = text + " Programming"; // "  Hello Java   Programming"
// 转换大小写
System.out.println(text.toUpperCase()); // "  HELLO JAVA  "
System.out.println(text.toLowerCase()); // "  hello java  "
// 去除首尾空格
System.out.println(text.trim()); // "Hello Java"
// 获取子串
System.out.println(text.substring(2, 7)); // "Hello" (从索引2开始,到索引7之前)
// 查找字符或子串
System.out.println(text.indexOf('J')); // 输出 8
System.out.println(text.contains("Java")); // 输出 true
// 替换
System.out.println(text.replace("Java", "Python")); // "  Hello Python  "
// 分割
String[] parts = text.trim().split(" "); // ["Hello", "Java"]
for (String part : parts) {
    System.out.println(part);
}

charString 的关系与转换

它们之间可以相互转换。

1 char -> String

有多种方法可以将一个 char 转换为 String

char ch = 'A';
// 方法1: 使用 String.valueOf()
String str1 = String.valueOf(ch);
// 方法2: 使用 构造函数
String str2 = new String(String.valueOf(ch)); // 或者 new String(new char[]{ch})
// 方法3: 使用 空字符串连接 (最简单)
String str3 = "" + ch;
System.out.println(str1); // A
System.out.println(str2); // A
System.out.println(str3); // A

2 String -> char

从一个 String 中获取 char

String str = "Hello";
// 方法1: 使用 charAt(index) 获取指定位置的字符
char firstChar = str.charAt(0); // 'H'
char secondChar = str.charAt(1); // 'e'
// 注意:如果索引越界,charAt() 会抛出 StringIndexOutOfBoundsException
// 方法2: 将 String 转换为 char[] 数组
char[] charArray = str.toCharArray(); // ['H', 'e', 'l', 'l', 'o']
System.out.println(charArray[0]); // H

StringBuilderStringBuffer(性能补充)

由于 String 的不可变性,在需要频繁进行字符串拼接、修改的场景下(例如循环中拼接大量字符串),如果直接使用 或 concat(),会产生大量临时的 String 对象,严重影响性能。

这时就应该使用 StringBuilderStringBuffer

  • StringBuilder:可变的字符序列。非线程安全,但性能更高,在单线程环境下是首选。
  • StringBuffer:可变的字符序列。线程安全(方法大多用 synchronized 修饰),但性能较低。
// 低效的方式(不推荐在循环中使用)
String result = "";
for (int i = 0; i < 1000; i++) {
    result = result + i; // 每次循环都创建一个新的 String 对象
}
// 高效的方式(推荐)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i); // 在原有的对象上进行修改,不创建新对象
}
String efficientResult = sb.toString();

总结与对比

特性 char String
类型 基本数据类型 引用数据类型(java.lang.String 类)
含义 表示单个 Unicode 字符 表示一个字符序列(字符串)
不可变性 可变 不可变
内存 栈内存 堆内存(字符串池优化)
表示 单引号 'A' 双引号 "Hello"
默认值 '\u0000' null
主要用途 存储单个字符,进行字符级别的操作 存储和处理文本,如句子、单词、文件路径等
性能 简单快速 频繁修改时性能差,应使用 StringBuilder
关系 String 内部由 char[] 实现 可以方便地与 char 相互转换

何时使用 char 当你只需要处理一个独立的字符时,检查一个字符是否是数字、字母,或者进行字符的加密/解密等。

何时使用 String 当你需要处理任何长度的文本时,存储用户名、文件内容、消息、SQL 语句等,这是绝大多数文本处理场景的选择。

分享:
扫描分享到社交APP
上一篇
下一篇