在 Java 开发中,String类是我们日常使用频率最高的类之一。无论是用户输入、数据处理还是日志输出,都离不开字符串的操作。今天这篇文章,我们就从基础出发,结合实例聊聊String类的核心特性、创建方式以及常用方法,帮你彻底搞懂字符串的那些事儿。
一、为什么要学 String 类?
String类位于java.lang包下(无需手动导入),用于表示字符串。Java 中所有的字符串字面量(比如"Hello")都是String类的对象。可以说,只要写 Java 代码,就一定会和String打交道。
比如我们用Scanner接收用户输入时,获取的内容本质上就是字符串;处理文本数据时,拼接、截取、替换等操作也都依赖String类的方法。学好String,能帮你搞定 80% 以上的文本处理场景。
二、String 类的核心特性:不可变性
在开始具体操作前,必须先明确String类的一个核心特性:字符串一旦创建,其内容就无法修改。
举个例子:
String name = "Rebbit";
String statement = "一定会成功";
System.out.println(name + statement); // 输出:Rebbit一定会成功
这里的name + statement看似是 “修改” 了字符串,实则是创建了一个新的字符串对象,原有的name和statement对象内容并未改变。
这种 “不可变性” 是由String类的底层实现决定的(底层是字符数组char[],且被final修饰),这一特性也影响了String对象的创建和使用方式。
三、String 对象的创建:两种方式的区别
创建String对象有两种常见方式,它们的底层原理和内存占用有很大区别,初学者很容易混淆,这里重点讲清楚。
1. 直接赋值(推荐)
String s1 = "abc";
String s2 = "abc";
- 原理:Java 会维护一个 “字符串常量池”(位于方法区),当使用直接赋值时,JVM 会先检查常量池中是否存在该字符串:
- 若存在,直接复用(让变量指向常量池中的对象);
- 若不存在,在常量池中创建该字符串,再让变量指向它。
- 优势:复用对象,节省内存。
2. 使用new关键字
// 空参构造:创建空白字符串
String s3 = new String();
// 传入字符串:根据已有字符串创建新对象
String s4 = new String("abc");
// 传入字符数组:将字符数组转为字符串
char[] chs = {'a', 'b', 'c'};
String s5 = new String(chs);
// 传入字节数组:将字节数组转为字符串(常用于网络数据转换)
byte[] bytes = {97, 98, 99}; // 97对应'a',98对应'b'(ASCII码)
String s6 = new String(bytes);
- 原理:无论常量池中是否存在该字符串,
new关键字都会在堆内存中创建一个新的对象。 - 注意:
new String("abc")会导致创建两个对象(若常量池中没有 “abc”):一个在常量池,一个在堆内存。
String s1 = "abc"; // 直接赋值,指向常量池
String s2 = new String("abc"); // new创建,指向堆内存
System.out.println(s1 == s2); // 输出false(==比较地址值,两者地址不同)
System.out.println(s1.equals(s2)); // 输出true(equals比较内容,内容相同)
==:对于基本类型比较值,对于引用类型(如String)比较地址。equals():String类重写了该方法,用于比较字符串内容是否相同。
四、String 类的常用方法(附实例)
除了上述的equals(),String类还有很多实用方法,这里结合场景讲解几个高频使用的:
1. 忽略大小写比较:equalsIgnoreCase()
String s1 = "Abc";
String s2 = "aBC";
System.out.println(s1.equalsIgnoreCase(s2)); // 输出true
适用于不区分大小写的场景(比如验证码校验)。
2. 获取字符串长度:length()
String s = "Hello World";
System.out.println(s.length()); // 输出11(空格也算一个字符)
3. 获取指定位置字符:charAt(int index)
String s = "Hello";
char c = s.charAt(1); // 获取索引为1的字符(索引从0开始)
System.out.println(c); // 输出'e'
4. 截取子串:substring(int beginIndex, int endIndex)
String s = "abcdefg";
// 从索引2开始,到索引5结束(包含begin,不包含end)
String sub = s.substring(2, 5);
System.out.println(sub); // 输出"cde"
- 若只传
beginIndex,则截取到字符串末尾。
5. 替换字符 / 字符串:replace(CharSequence target, CharSequence replacement)
String talk = "你玩的真好,以后别玩了,脏话";
String filtered = talk.replace("脏话", "***");
System.out.println(filtered); // 输出:你玩的真好,以后别玩了,***
常用于敏感词过滤、格式替换等场景。
6. 分割字符串:split(String regex)
String str = "张三,20,男";
String[] parts = str.split(","); // 按逗号分割
for (String part : parts) {
System.out.println(part);
}
// 输出:
// 张三
// 20
// 男
适用于解析 CSV 格式数据、日志拆分等场景(注意:regex是正则表达式,特殊字符需转义)。
7. 转换大小写:toLowerCase()/toUpperCase()
String s = "Hello World";
System.out.println(s.toLowerCase()); // 输出"hello world"
System.out.println(s.toUpperCase()); // 输出"HELLO WORLD"
五、小技巧与注意事项
-
字符串拼接的效率问题:
用+拼接字符串时,由于String的不可变性,每次拼接都会创建新对象,效率较低。若需频繁拼接(比如循环中),建议使用StringBuilder或StringBuffer。 -
避免
null引发的空指针异常:
调用equals()时,若变量可能为null,建议写成:
if ("abc".equals(s)) { ... }(用常量调用方法,避免s为null时报错)。 -
常量池的复用:
直接赋值的方式会复用常量池对象,因此对于频繁使用的字符串(如 “男”“女”),优先用直接赋值。
六、总结
String类是 Java 中最基础也最核心的类之一,掌握它的创建方式、不可变性以及常用方法,能让你在处理文本数据时事半功倍。本文从基础概念到实战方法做了系统梳理,建议结合代码多动手练习(比如尝试实现一个简单的用户注册功能,用String处理用户名、密码的校验),加深理解。
3877

被折叠的 条评论
为什么被折叠?



