Java中基于字符串的理解

Java中字符串核心是 String 类(不可变),搭配 StringBuilder (可变非线程安全)、 StringBuffer (可变线程安全),以下从核心特性、底层原理、常用操作、性能优化、场景选型等维度拆解:

一、核心特性(底层本质)

- 不可变性(String核心):底层是 private final char[] (JDK9后改为 byte[] +编码标识),初始化后字符数组无法修改,所有拼接、替换操作都会生成新String对象。

- 常量池缓存:字符串字面量(如 "abc" )会存入方法区常量池,通过 intern() 方法可手动将堆中String对象入池,实现复用(避免重复创建)。

- 线程安全:String因不可变天然线程安全,StringBuilder非线程安全(效率高),StringBuffer通过 synchronized 修饰方法保证线程安全(效率低)。

二、底层存储差异(JDK8 vs JDK9+)

- JDK8:存储结构为char[](每个字符占2字节),编码兼容简单,适用于主要存储ASCII字符的场景(存在空间浪费)。

- JDK9+:存储结构为byte[] + coder(编码标识),能节省空间(ASCII占1字节),适配混合编码场景(自动适配UTF-8/UTF-16)。

三、常用操作(高频API+细节)

1. 创建方式(3种核心)

 - 字面量创建: String s = "abc"; (优先从常量池获取,无则创建)。

- 构造方法: String s = new String("abc"); (堆中创建对象,可通过 intern() 入池)。

- 字符/字节数组转换: new String(char[] arr) 、 new String(byte[] arr, Charset.forName("UTF-8")) (需指定编码避免乱码)。

2. 关键API(避坑点)

- 比较: equals() (内容比较,大小写敏感)、 equalsIgnoreCase() (忽略大小写)、 == (地址比较,常量池对象==为true,堆对象==为false)。

- 拼接: + (编译后转为StringBuilder.append(),循环中使用会频繁创建对象)、 concat() (仅拼接字符串,效率低于StringBuilder)。

- 替换: replace(char old, char new) (全量替换)、 replaceAll(String regex, String replacement) (正则替换,需注意转义,如 . 需写为 \\. )。

- 分割: split(String regex) (正则分割,空字符串可能产生空数组,如 "a,,b".split(",") 结果为 ["a","","b"] )。

- 其他: trim() (去除首尾空白字符,不包含Unicode空白)、 strip() (JDK11+,去除所有Unicode空白)、 substring(beginIndex, endIndex) (JDK7+直接截取字符数组,JDK6会复制原数组,效率低)。

四、性能优化技巧

- 循环拼接优先用 StringBuilder :避免 String s = ""; for(...) {s += i;} (每次循环创建新对象),改用 StringBuilder sb = new StringBuilder(); sb.append(i); ,最后 sb.toString() 。

- 预指定容量: new StringBuilder(1024) (默认容量16,扩容时需复制数组,预指定可减少扩容次数)。

- 常量池复用:频繁使用的字符串(如配置项)用字面量创建,或通过 intern() 入池(注意:JDK7+常量池移到堆中,过度使用可能导致OOM)。

- 避免不必要的对象创建:如 String s = new String("abc"); 可直接改为 String s = "abc"; ,减少堆对象创建。

五、场景选型(String vs StringBuilder vs StringBuffer)

- String:不可变、线程安全、效率低,适用于字符串不频繁修改的场景(如常量、配置)。

- StringBuilder:可变、非线程安全、效率高,适用于单线程下频繁修改的场景(如循环拼接、字符串构建)。

- StringBuffer:可变、线程安全、效率中,适用于多线程下频繁修改的场景(如并发场景的日志拼接)。

六、常见坑点

- 空指针问题: String s = null; s.equals("a") 会抛空指针,应改为 "a".equals(s) 或 Objects.equals(s, "a") 。

- 正则相关API: replaceAll() 、 split() 是正则匹配,如想匹配普通字符(如 * 、 ? ),需先转义。

- 不可变性误解: String s = "a"; s += "b"; 后 s 指向新对象,原 "a" 仍在常量池,并非修改原对象。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值