Java中数组传参修改会永久改变,为何String对象不行?
为什么数组修改后原对象变化,String却不会?
首先明确核心:Java里所有参数传递都是值传递。对于对象类型(包括数组、String),传递的是对象引用的副本——简单说就是把原变量里存的「对象地址」复制一份传给方法参数,而非对象本身。
一、数组被修改的原因
数组是可变对象,它的内容可以直接修改。在changeFirstEntryToZero方法里,array[0] = 0是通过参数里的引用副本,找到原数组对象并修改了它的内部元素。原数组对象的内存地址没变,外部的testArray仍然指向这个对象,所以打印时能看到变化。
对应的方法代码:
static int[] changeFirstEntryToZero(int[] array) { array[0] = 0; // 操作的是原数组对象的内部内容 return array; }
二、String没被修改的原因
String是Java的不可变对象——它的内部字符数组被private final修饰,一旦创建就无法修改内容。在changeString方法里,s = "changed"不是修改原"helloWorld"对象的内容,而是让方法里的参数引用s(原引用的副本)指向了一个新的String对象"changed"。外部的testString仍然指向原来的"helloWorld",所以打印结果不变。
对应的方法代码:
static String changeString(String s) { s = "changed"; // 参数引用指向新对象,和原对象无关 return s; }
是否存在其他操作会意外永久修改String?
常规开发中不存在。因为String的不可变性是Java语言层面强制保证的:
- String类被
final修饰,不能被继承,防止子类破坏不可变性 - 内部的字符数组
value是私有且final的,外部没有直接修改它的途径 - 所有看似修改String的方法(比如
replace、toUpperCase),本质都是返回新的String对象,原对象不会被改变
唯一能修改String内部内容的方式是通过反射,但这属于非常规操作,会破坏String池的一致性,甚至引发奇怪的bug,实际开发中绝对不允许这么做。
内容的提问来源于stack exchange,提问作者grecode97
相关产品推荐
相关产品推荐

