关于String在内存的表示和intern方法

本文详细探讨了Java中String对象的存储位置,包括在堆和字符串常量池中的区别,以及不同创建方式下的内存分配。讲解了字面量拼接与变量拼接时的优化过程,并对比了JDK1.6和1.7以后intern方法的行为差异。此外,还分析了如何通过intern方法确保字符串在常量池中的唯一性。
摘要由CSDN通过智能技术生成

内存

String 字符串的存储位置在JAVA7之后存储在堆空间中的字符串常量池中。而此前是存储在永久区之中。(java8之后jvm中的方法区的实现时元空间,而此前是永久区)

不同创建方式在内存的位置

  1. String str = "this is str"; 这种方式通过字面量的方式创建一个字符串,此时会直接在堆的常量池中创建此字符串(如果之前已经创建过了,由于字符串的不变性,会使用之前的那个)。
  2. String str2 = new String(“this is str”); 这种方式会在堆空间中创建一个String类型的对象,并且在字符串常量池中创建对应的字符串,即会创建两个对象。但是str保存的是所创建对象的引用,而非指向常量池,即调用 str2 == str ,结果为false。结果如下:在这里插入图片描述在这里插入图片描述
  3. 通过字符串拼接的方式创建一个字符串:
    3.1 String str = "a"+"a"; 这种方式属于字面量与字面量的拼接,此时会进行编译期优化,此时相当于str=“aa”,即str还是指向常量池中的aa,验证:
    在这里插入图片描述
    在这里插入图片描述
    3.2 String str = "a"; String str2= str+"a";,这种方式属于字符串中存在变量的拼接方式,此时会创建一个新的String对象,然后创建一个StringBuilder 对象,然后调用StringBuilder的append方法把这两个字符串拼接到一起,最后,通过StringBuilder对象的toString方法返回了一个字符串对象,值得注意的是,toString方法中的内容是:
    在这里插入图片描述
    它是new了一个String对象,而且是通过char数组的方式创建的,也就是说不会在字符串常量池中创建对应的字符串,即这种方式创建方式在字符串常量池中不会有“aa”。验证如下:
    在这里插入图片描述
    在这里插入图片描述
    结果表明他们不是一个对象。
  4. String str3 = new String("a") + new String("a"); 这种方式首先会分别创建两个String对象,然后字符串常量池中只会有一份“a”,验证:
    在这里插入图片描述
    在这里插入图片描述
    随后,会创建一个StringBuilder对象,并通过它的toString方法new了一个String并返回,内容就是连个字符串的拼接,并且是字符数组方式创建的,因此在字符串常量池中不存在“aa”。
    在这里插入图片描述
    在这里插入图片描述

intern

如果不是用双引号声明的String对象,可以使用String提供的intern方法: intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。也就是说,如果在任意字符串上调用string.intern方法,那么其返回结果所指向的那个类实例,必须和直接以常量形式出现的字符串实例完全相同。
例如:
在这里插入图片描述
第一种方式以字面量的方式在常量池中创建了一个字符串,而第二种方式创建了一个String对象,并且由于常量池中已经有这个字面量,所以只会保证在其中只有一个字符串。此时比较二者发现不同:
在这里插入图片描述
而如果用intern方法创建:
在这里插入图片描述
此时结果:
在这里插入图片描述
即此时会在常量池中查看是否有该字符串,如果存在就会直接把该字符串引用赋值给a,否则就现在常量池中创建这个字符串再赋值引用给a。

两个jdk版本intern的区别

jdk1.6中,将这个字符串对象尝试放入串池。

  • 如果串池中有,则并不会放入。返回已有的串池中的对象的地址
  • 如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址

Jdk1.7起,将这个字符串对象尝试放入串池。

  • 如果串池中有,则并不会放入。返回已有的串池中的对象的地址
  • 如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址,这可以节省堆中的内存(创建的对象数减少了)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值