String 内存值不变性
package org.onepiece; import java.lang.String; public class Main { public static void main(String[] args) { String str = new String("123"); str = new String("456"); } }
String str = new String("123") ;会在内存中的某个位置开辟一块内存,其中存放"123"字符串,随后让str指向刚开辟的内存地址。
str = new String("456");系统会重新开辟新的内存,在其中存放字符串"456",随后 str 会指向它,从而得到新的值。
此时第一个开辟的内存空间的值没改变,还是字符串"123",但是 str 已经不再指向它了。
也就是说,发生 str = new String("456");操作后不是在原来第一次开辟的内存上把字符串"123"的值修改成字符串"456",而是会开辟一块新的内存放字符串"456"。原先第一次开辟的内存的值是不变的。
此时存放字符串"123"的内存由于没有对象会引用,因此它就成了内存碎片,要在下次Java虚拟机回收内存时才会被回收。
package org.onepiece; import java.lang.String; public class Main { public static void main(String[] args) { String num = "1"; for (int i = 0; i < 100; i++) { num = num + i; /** *频繁地进行字符串连接操作 * 此时会频繁地开辟新的内存空间存放新的值,旧的内存空间会随之废弃。 * 这样会造成大量的内存损耗。 * */ } println(num); } private static void println(Object obj) { System.out.println(obj); //sout } }
虽然虚拟机会对此进行优化,但在代码时尽量避免在循环中大批量出现针对字符串的操作(不仅限于连接)。
因为这样会频繁地生成内存碎片,导致内存性能问题。
如果遇到这种业务需求,建议改成使用 StringBuilder对象。

浙公网安备 33010602011771号