String对象的探究(new String到底创建了多少对象?)

1. 前言(String)

  • 内部结构
    1. jdk8及以前,使用的是char[]
    2. jdk8以后,使用的是byte[]+字符编码标识
  • 不可变性
    1. 通过字面量的方式给一个字符串赋值,是直接声明在字符串常量池
    2. 字符串常量池中是不会存储相同内容的字符串的
  • 内存分配
    1. jdk6及以前:字符串常量池存放在永久代
    2. jdk6之后:调整到了Java堆
  • intern()方法
    1. jdk6及以前:如果字符串常量池中有,则不会放入,而是返回已有的字符串常量池中对象的地址;如果没有,会把此对象复制一份(创建一份新的),放入字符串常量池中,并返回字符串常量池中对象的地址
    2. jdk6之后:如果字符串常量池中有,则不会放入,而是返回已有的字符串常量池中对象的地址;如果没有,会把此对象的引用地址复制一份,放入字符串常量池中,并返回字符串常量池中的引用地址

2. new String()到底创建了多少对象(java8举例)?

2.1. new String(“abc”):2/1

  • 如果在常量池中“abc”不存在,则分别在常量池中和堆中创建“abc”字符串常量以及字符串实例对象
  • 如果在常量池中“abc”不存在,则只在字符串实例对象
  • 无论如何都会创建字符串实例对象

2.2. String str = “a” + “b” + “c”:1

  • 这个“a + b + c”在底层会在编译阶段编译为“abc”JAVA在编译器编译时,常量与常量的拼接会得到编译优化为“abc”并放入常量池中

2.3. String abc =“a”+ new String(“bc”):5

在这里插入图片描述

  • 这里假设字符串常量池中无数据
  • 只要不是单纯的直接使用字符串字面量相加就会在运行时产生一个StringBuilder对象用于字符串连接,且不会进行此处的字符串编译优化
  • 根据如上图所示,会产生:StringBuilder字符串常量astring(”bc“)bc字符串常量StringBuilder.toString() 方法:new一个String(“abc”)对象,一共五个对象

2.4. String str = new String(“a”) + new String(“b”):6

在这里插入图片描述* 这里假设字符串常量池中无数据

  • 根据如上图所示,会产生:StringBuilderstring(”a“)字符串常量astring(”b“)b字符串常量StringBuilder.toString() 方法:new一个String(“ab”)对象,一共六个对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值