String 的创建方式及内存分配的方式

String 类分析(JDK1.8)

在这里插入图片描述
String 对象是对char数组进行了封装实现的对象,主要有2个成员变量:char 数组、hash值。

String 对象的不可变性

看String的源码,不难发现,String类被final修饰了,而且char 数组也被final修饰,我们知道被final修饰代表该类不可被继承,而且char数组 被final+private 修饰,代表了Sting对象不可被更改。
java实现的这个特性叫Sting对象的不可变性,即Sting对象一旦被创建,就不能再对它改变。

这样做的好处?

1、保证Sting对象的安全性。
2、保证hash属性值不会频繁变更,确保唯一性,使得类似HashMap容器才能实现相对应的key-value缓存的功能。
3、可以实现字符串常量池。

String 的创建方式及内存分配的方式

String str=“abc”

当代码使用这种方式创建时,JVM首先检查该对象是否存在字符串常量池中,若在,就返回该对象的引用,否则新的字符串将在常量池中创建,这种方式可以减少同一值得字符串对象的重复创建,节约内存。
在这里插入图片描述

String str = new String(“abc”)

1、首先在编译类文件时,“abc”常量字符串将会放在常量池中,在类加载的时候,“abc”将会在常量池中创建;
2、其次在调用new时,JVM命令将会调用String的构造函数,同时引用常量池中的“abc”字符串,在堆内存中创建一个String对象;
3、最后str将引用String对象。
在这里插入图片描述

对象直接赋值

对象在堆中创建的同时,会在常量池中创建一个字符串对象,复制到堆中。
具体的复制过程是先将常量池中的字符串压入栈中,在使用 String 的构造方法时,会拿到栈中的字符串作为构方法的参数。 这个构造函数是一个 char 数组的赋值过程,而不是 new 出来的,所以是引用了常量池中的字符串对象。存在引用关系。

public void mode3(){
        Location location = new Location();
        location.setCity("深圳");
        location.setRegion("南山");
}

在这里插入图片描述

String str2= “ab”+ “cd”+ “ef”;

编程过程中,字符串的拼接很常见。但是 String 对象是不可变的,如果我们使用 String 对象相加,拼接我们想要的字符串,是不是就会产生多个对象,首先会生成 ab 对象,再生成 abcd 对象,最后生成 abcdef 对象,从理论上来说,这段代码是低效的。 而编译器会自动优化了这行代码,编译后的代码,你会发现编译器自动优化了这行代码,如下 String str= “abcdef”;

intern

String 的 intern 方法,如果常量池中有相同值,就会重复使用该对象,返回对象引用。

public static void main(String[] args) {
        //去字符串常量池找到是否有等于该字符串的对象,如果有,直接返回对象的引用。
        String a =new String("xiaoma").intern();// new 对象、xiaoma字符常量池创建
        String b = new String("xiaoma").intern();// b ==a。
        if(a==b) {
            System.out.print("a==b");
        }else{
            System.out.print("a!=b");
        }
    }

1、new Sting() 会在堆内存中创建一个 a 的 String 对象,"xiaoma"将会在常量池中创建
2、在调用 intern 方法之后,会去常量池中查找是否有等于该字符串对象的引用,有就返回引用。
3、调用 new Sting() 会在堆内存中创建一个 b 的 String 对象。
4、在调用 intern 方法之后,会去常量池中查找是否有等于该字符串对象的引用,有就返回引用。

所以 a 和 b 引用的是同一个对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值