String引用在replace方法中的工作机制及原对象引用去向问题
关于String.replace()后原对象引用的问题
先把你给出的代码格式化一下,方便理解:
public class Test { public static void main(String[] args){ String s = "My name is Java"; // Step 1 s = s.replace("Java", "Python"); // Step 2 System.out.println(s); } }
首先再敲个黑板:String是不可变的——任何看似修改String的方法(比如replace、substring这类),都不会改动原对象本身,而是会创建一个全新的String对象返回。
回到你的问题:执行完Step 2之后,还有谁指向"My name is Java"这个对象?
分两种场景来说明:
- 在你这段代码的局部范围内:没有其他显式的引用变量指向它了。因为Step 1里的引用
s已经被重新赋值,指向了replace方法返回的新对象"My name is Python",原对象失去了来自代码中变量的引用。 - 从JVM的字符串常量池角度看:因为"My name is Java"是用字面量直接声明的,它会被存入字符串常量池。JVM的常量池会持有这个对象的引用,直到满足垃圾回收的触发条件(不过常量池中的字符串对象通常存活周期较长,除非是一些特殊的动态生成场景)。
举个额外的例子帮你理解,如果代码改成这样:
public class Test { public static void main(String[] args){ String s = "My name is Java"; // Step 1 String s2 = s; // 新增一个引用绑定原对象 s = s.replace("Java", "Python"); // Step 2 System.out.println(s2); // 这里会输出"My name is Java" } }
这时候执行完Step 2,s2还会牢牢指向原对象,但在你最初的代码里没有这类额外引用,所以就只有常量池的引用还挂着它啦。
内容的提问来源于stack exchange,提问作者linuxman
相关产品推荐
相关产品推荐

