闲聊
不知道啥时候开始写闲聊有了一丝尴尬,最近这几天疯狂加班,把心态搞的是崩崩的,崩的我看见那块代码就难受,做梦都是那几个功能,好几天夜里两点才到家。好在组里来了股新生力量,有人陪着一起加班,心里好受多了。
每个阶段有每个阶段焦虑的事吧,短暂性的躺平持续性焦虑。
Java中string的引用传递
写一篇记录前几天遇到的个小问题,这个问题说起来很尴尬,还挺基础的。公司的Java项目的代码都要严格按照checkStyle约定的规范编写,不符合规范就会打不出Jar包。
所以遇到复杂的逻辑只能拆分成数个子函数进行处理,拆分成子函数就会有一些参数割裂开,比如主函数逻辑里的一些字符串了,Map了,List了诸如此类的子函数要想用必须用参数传递的方式传到子函数里。这里就要注意String字符串的传递。
先看一段代码,stackoverflow上说很多人会回答错程序的输出。
public static void main(String[] args) {
String x = new String("ab");
change(x);
System.out.println(x);
}
public static void change(String x) {
x = "cd";
}
如果你觉得是cd那这篇没白看,答案是ab。
那么这这段程序到底执行了什么,首先当"ab"创建后,Jvm在堆中分配对象所需内存空间。然后栈中的变量x指向了"ab"。
x保存了一个指向String对象的地址。x只是保存一个内存地址。在Java中只有值传递。当x通过参数传递给change()方法后,x被拷贝了一份,此时指向的内存地址还是跟主方法是一致的。接着change()创建了另一个对象"cd",并且将x指向了不同的地址空间。这时change()方法里的x就指向了"cd"。与主方法的对象就不是一个对象了。

上面的问题跟String的不可变没有关系。即使是StringBuilder,结果也一样。关键是变量存储的是引用,意思是在方法里改变了变量的引用地址,后续无论做什么改变都不会影响最初进来引用对象。
所以对于String字符串传递的情况只要保证进来的参数指向不发生变化即可,比如可以把change函数改成StringBuilder参数
public static void change(StringBuilder x) {
x.delete(0, 2).append("cd");
}
这样其实操作的是相同的内存引用。
嗯,这篇有点短,但还是很精悍的!




