Java学习记录0005 | 关于String底层浅析

String类对象存储的本质是final修饰的字符数组value[],一旦创建后对象就不可变,当我们看到String对象可以增删改时,实际上底层经过了临时对象的创建和字符数组的拷贝。

在做一道String字符串拼接练习时使用了三种做法:

一、

public class Main {
	public static void main(String[] args) {
        String str1 = "I love ";
		String str2 = "China";
		str1 = str1.concat(str2);
		str1 = str1.toUpperCase();
		System.out.println(str1);
	}
}

 str1首先指向常量池中的字符串常量"I love"。在调用String类的方法concat()和str2拼接后,结果赋值给str1,这个过程实际上在底层创建了新的字符数组,并创建String的临时对象,将这个临时对象的地址赋给str1。也就是说str1开始指向常量池的对象,拼接字符串后又指向堆中的临时对象(被指向后不再临时)。在改变大小写的操作时,底层同样又在堆中创建了新的对象,str1又改变指向了全大写的字符串对象。最终输出。


二、

public class Main {  
    public static void main(String[] args) {  
        String str1 = "I love ";  
        String str2 = "China";  
        System.out.println(str1.concat(str2).toUpperCase());  
    }  
}

 在这个做法中,没有给新创建的String对象显示的声明一个引用,而是直接输出到控制台。虽然没有将对象赋值给一个变量,但在底层依旧和第一种一样创建了两个新的String类型变量。

三、 

public class Main {
	public static void main(String[] args) {
        String str1 = "I love ";
		String str2 = "China";
		String str3 = str1 + str2;
		System.out.println(str3.toUpperCase());
	}
}

第三种做法没有调用concat()方法,而是使用+操作符连接两个指向常量池对象的常量。在此过程中,底层先创建了StringBuilder类的临时对象,并调用append()方法对两个字符串对象进行拼接,最后调用toString()方法创建新的String对象,这个对象包含了拼接后的内容,将这个String对象的地址赋给str3,最后调用大写函数输出。

总结

1、第一种做法直接将新创建的Sting对象赋值给str1,会造成原来str1指向的对象没有指针指向,会造成垃圾对象;

2、第二种做法直接调用了新创建的对象,当输出结束后同样会造成垃圾对象,并有被垃圾回收机制回收的风险;

3、第三种做法

(1)当使用+操作符来连接(拼接)字符串时,实际上在编译时,如果两个字符串都是编译时常量(即直接在代码中指定的字符串字面量),并且没有与其他变量进行拼接,那么这些字符串在编译时就会被放入字符串常量池中。当使用+操作符拼接这些字符串时,编译器会计算拼接后的结果,并将这个新的字符串字面量也放入常量池中。在运行时,这个拼接后的字符串直接从常量池中获取,不会有任何额外的内存分配或StringBuilder的使用。

(2)虽然str1str2都是指向字符串常量池中的字符串,但是当使用str1 + str2这样的表达式时,由于存在变量,编译器就不能确定字符串的最终值。因此,编译器会生成字节码,这些字节码在运行时会使用StringBuilder来动态地拼接字符串。这是为了提高性能,因为创建多个中间String对象(在每次拼接时)会导致不必要的内存分配和垃圾回收。使用StringBuilder可以避免这种开销,因为它允许在单个字符数组中逐步构建最终的字符串。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值