【Java深入理解】String str = “a“ + “b“ + “c“到底创建了几个对象?

String str = “a” + “b” + “c"到底创建了几个对象?这是我们在讨论中最经常遇到的一个问题同时也是面试题。我们都知道在Java中从”.java"文件编译成".class"文件的过程,会有一个优化器去优化我们的代码。这个问题需要分成三种情况去考虑,下面我们就来分析这三种情况!!

前言
在JVM(JDK8)的内存结构中有一块区域叫作字符串常量池,这块区域存储了两样东西,分别是“字面量”和“符号引用”。字面量也就是一串字,例如String str = “abc” 这里的"abc"就是字面量。符号引用是用于定位引用指向的问题。(JDK8完完全全把字符串常量池从方法区搬到堆中了)

一、第一种情况(常量相加)

String str = “a” + “b” + "c

因为这种情况是常量之间相加,经过编译器优化成了String str = “abc”,所以答案是创建了一个对象。“a”、“b”、"c"这些都是常量,因为它们是final修饰放在字符串常量池中的对象(注意:字面量也是对象)

我们通过javac编译,然后反编译后的结果和内存分配情况如下

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.soft.wesker;

public class Test {
    public Test() {
    }

    public static void main(String[] var0) {
        String var1 = "abc";
    }
}

在这里插入图片描述
二、第二种情况(变量相加)

String a = “a”;
String b = “b”;
String c = “c”;
String str = a + b + c;

因为这种情况是变量之间相加,已经不是之前的常量相加了,经过编译器优化成了StringBuilder,所以答案是创建了三个对象。new StringBuilder()、new String()、“abc”,因为最终会通过StringBuilder()里面的toString()方法进行new String(“abc”)类型转换。

我们通过javac编译,然后反编译后的结果和内存分配情况如下

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.soft.wesker;

public class Test {
    public Test() {
    }

    public static void main(String[] var0) {
        String var1 = "a";
        String var2 = "b";
        String var3 = "c";
        (new StringBuilder()).append(var1).append(var2).append(var3).toString();
    }
}


在这里插入图片描述
三、第三种情况(无优化)

String str = “a” + “b” + "c

如果不考虑优化的情况下,这一共是创建了5个对象的,因为一个双引号就是一个字面量(对象),这里创建了5个对象,分别是"a"、“b”、“c”、“ab”、“abc”。

下面是内存分配情况
在这里插入图片描述
总结
在没有明确的题目的情况下,我们讨论这个问题,有时候没有正确的答案,大家的想法和说法都不一样,需要分情况去讨论,这是一个争议题,比如还有人把char[]或者byte[]也算进去了。
最后我们还需要考虑一个问题,在创建字面量的时候,JVM会先从字符串常量池中寻找是否已经存在,如果已经存在则直接返回引用,不存在就会先创建一个字面量,然后再返回引用。所以就会出现创建了0个对象的问题

  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Archie_java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值