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); }
一步步拆解执行逻辑:
word存储的是字符串"word"的内存地址,指向这个具体对象。- 调用
method时,把word里的地址拷贝给形参str,此时str和word指向同一个"word"对象。 str.substring(0,1)会生成一个全新的字符串对象"w",然后把str这个局部变量的指向换成新对象的地址——这一步只是修改了str自身的引用,和word没有任何关系。- 方法执行完毕后
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
相关产品推荐
相关产品推荐

