从jdk1.8版本的jvm角度来理解String str = "a" + "b";创建了几个对象

前言

  • 话不多说直接进入正题

一、三道面试题


  • Q1:如下代码一共创建几个对象?
    String str = "a" + "b";
    
  • A1:emmm,刷过面试题的肯定会这么回答:四个!因为String是final的,所以会创建 "a", "b", "ab"三个String对象以及一个str对象,它指向"ab"这一个字符串。我相信大多数人都是这么回答的,那么到底是不是呢?咱们以jdk1.8中jvm的角度来验证下(会使用到字节码相关的知识点)
  • 使用jdk1.8解析:

    1.新建java类并添加如下代码:

    public class Test {
    
        public static void main(String[] args) {
            String str = "a" + "b";
        }
    }
    

    2.使用javac命令或idea中将它编译成class文件

    javac Test.java
    

    3.使用javap -c命令进行反编译查看字节码指令, 如下图所示
    在这里插入图片描述
    由上可以看到,实际上创建的只有一个对象ab, 如果说还要有一个,那就是一个存放在栈里的str引用对象所以在jdk1.8版本的jvm中,String str = "a" + "b"; 如果把引用对象也算进去的话,这里只创建了两个对象,如果不算引用对象的话,这里只创建了一个对象


  • Q2: 以下代码一共创建了几个对象?

    String a = "a";
    String b = "b";
    String ab = a + b;
    
  • A2: emmm, 刷过面试题的又会说: 不算引用对象的话,有"a", "b", "ab"一共是3个对象,算引用对象的话,有"a", "b", "ab",引用对象a,引用对象b,引用对象ab一共是6个对象。咱们也从jvm的角度来解析下

  • 使用jdk1.8解析:

    1.新建java类并添加如下代码:

    public class Test {
    
        public static void main(String[] args) {
            String a = "a";
    	    String b = "b";
    	    String ab = a + b;
        }
    }
    

    2.使用javac命令或idea中将它编译成class文件

    javac Test.java
    

    3.使用javap -c命令进行反编译查看字节码指令, 如下图所示
    在这里插入图片描述

    由上可以看出,总共创建了a, b两个常量,后续new了一个StringBuild对象,String ab = “a” + “b”;这行代码使用的是StringBuild的append方法进行拼接的所以在此处,一共有6个对象,分别是"a", "b", 一个new出来的StringBuild对象,引用对象a, b, ab


  • Q3: 以下代码一共创建了几个对象?
    String str = new String("a" + "b" + "c");
    
  • A3: 这次咱们不猜了,直接分析jvm如何做的
    在这里插入图片描述
    这里一共创建了两个对象以及一个str的引用对象

二、总结

  • 由上可知,我们能发现jvm编译的几个特点:
    • 我们在方法内部定义的变量名在jvm内部没有被用到
    • 所有的字符串常量(类似于: “a” + “b”)的拼接,jvm都会把它优化,直接变成ab常量,所以中途不会创建"a", "b"两个对象。
    • 所有的字符串引用变量的拼接,如下
      	String a = "a";
      	String b = "b";
      	String ab = a + b;
      
      jvm都会在底层创建一个StringBuild变量并使用它的append方法进行拼接
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值