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

Java中方法的String参数为何无法成为实参的别名?

Java里String参数传递为啥“不按常理出牌”?

先掰正一个关键认知:Java里根本没有什么“别名传递”,所有参数都是按值传递。不管传的是基本类型还是对象,本质都是把变量的值拷贝一份给形参——对象类型的话,拷贝的是对象的引用地址,不是对象本身。

你的代码为啥没改到原变量?

看你写的这段代码:

public static void main(String[] args) {
    String word = "word";
    
    method(word);
    
    System.out.println(word); // Prints "word"
}
    
public static void method(String str) {
    str = str.substring(0, 1);
}

一步步拆解执行逻辑:

  1. word存储的是字符串"word"的内存地址,指向这个具体对象。
  2. 调用method时,把word里的地址拷贝给形参str,此时str和word指向同一个"word"对象。
  3. str.substring(0,1)会生成一个全新的字符串对象"w",然后把str这个局部变量的指向换成新对象的地址——这一步只是修改了str自身的引用,和word没有任何关系。
  4. 方法执行完毕后str被销毁,word依然指向原来的"word"对象,所以输出结果不变。

哪怕你用new String("word")初始化,结果也完全一致——不管是字符串常量池还是堆中的String对象,本质都是不可变的。

为啥你觉得普通对象是“别名”?

举个可变对象的例子,比如StringBuilder:

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("hello");
    modify(sb);
    System.out.println(sb); // 输出"helloworld"
}

public static void modify(StringBuilder sbParam) {
    sbParam.append("world");
}

这里看起来像是“别名生效”,其实是因为:

  • sbParam是sb引用的拷贝,二者指向同一个StringBuilder对象。
  • append方法是直接修改这个对象内部的内容,而非修改sbParam的指向。
  • 所以sb指向的对象状态被改变,输出结果随之变化。但如果在modify里写sbParam = new StringBuilder("new");,sb依然指向原来的对象,输出不会改变——这就和String的情况完全一致了。

String的特殊性:天生不可变

String是Java中的不可变类,所有看似修改String的方法(substring、replace、toUpperCase等),都不会修改原对象的内容,而是直接返回一个全新的String对象。所以你在方法里对str做的任何“修改”,都是生成新对象后让str指向它,完全碰不到原对象,也影响不到实参word。

一句话总结

Java从来都是按值传递,String的表现和其他对象没有区别——只是因为它不可变,没法通过形参修改原对象的内容,同时修改形参的指向也不会影响实参。所谓的“别名”错觉,只是因为可变对象可以通过形参修改内部状态而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:12:42