You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java字符串何时可修改?两段代码修改结果差异原因解析

Java字符串的“修改”真相

Java里的String是不可变类型——一旦创建,它内部的字符内容就再也没法改变。我们平时说的“修改字符串”,本质都是生成了新的String对象,然后让原来的变量重新指向这个新对象。常见的“修改”场景包括:

  • 用+拼接字符串时,每次拼接都会产生新的字符串对象
  • 调用substring()、replace()、toUpperCase()这类String方法时,这些方法不会改动原字符串,只会返回一个全新的字符串实例
  • 如果要真正在原容器里修改字符序列,得用StringBuilder或StringBuffer,它们的append()、insert()等方法可以直接修改内部的字符数组,最后通过toString()转成String对象

为什么两个版本输出不一样?

版本1的执行逻辑

在版本1的main方法里,这句代码:

str = str.substring(2, 3) + str.substring(1, 2) + str.substring(0, 1);

substring和+操作生成了新的字符串"orF",然后直接把main方法里的局部变量str改成指向这个新对象。后面打印的时候,自然输出的是新对象的内容。

版本2的问题根源

版本2里调用了processString(str),这里要搞懂Java的参数传递规则:Java里所有参数传递都是值传递。当你把main里的str传给processString时,传递的是原字符串引用的一个副本——也就是说,processString方法里的str是一个单独的局部变量,只是和main里的str指向同一个"Frog"对象而已。

在processString里,你把这个局部的str重新指向了新生成的"orF",但这只会改变方法内部这个局部变量的指向,完全影响不到main方法里原来的str。所以main里的str还是指向最初的"Frog",打印出来当然还是它。

让版本2生效的两种方式

  1. 让processString返回新字符串,在main里接收:
public static void main(String[] args) {
    String str = "Frog";
    str = processString(str); // 把返回的新对象赋值给原变量
    System.out.println(str);
}

public static String processString (String str) {
    return str.substring(2, 3) + str.substring(1, 2) + str.substring(0, 1);
}
  1. 用StringBuilder这种可变容器当参数(因为它是引用类型,修改内部状态会同步到原对象):
public static void main(String[] args) {
    StringBuilder str = new StringBuilder("Frog");
    processString(str);
    System.out.println(str);
}

public static void processString (StringBuilder str) {
    String newStr = str.substring(2, 3) + str.substring(1, 2) + str.substring(0, 1);
    str.replace(0, str.length(), newStr);
}

内容的提问来源于stack exchange,提问作者EthanAlvaree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:20:25