深入理解Java new String()方法

 更新时间:2021年06月17日 17:15:15   作者:小胖java攻城狮  
今天给大家带来的是关于Java的相关知识,文章围绕着Java new String()展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下

问题一:这段代码创建了几个对象?

String str1 = new String("aa");

答案是两个
“aa”对象和String对象

其中有一项是常量池
常量池在Class文件被加载的时候,会被加载进内存中的方法区中的运行时常量池,而运行时常量池里就包括字符串常量池,Class文件中的字符串在类加载时就会加载到字符串常量池中去

在这里插入图片描述

不过在周志明老师在深入java虚拟机中有说到,到了JDK1.7时,字符串常量池就被移出了方法区,转移到了堆里了。

String str1 = new String(“aa”);
"aa"就是被加载进去的字符串,我们可以看看Class文件

在这里插入图片描述

这里的aa在之后类加载的时候,会在字符串常量池里创建一个 "aa"对象,这是第一个对象类加载完成了之后,那就要开始正式执行代码了,执行该行代码时new一个"aa"的String对象存放在Java堆中,这是第二个对象创建完第二个对象后,虚拟机栈上的str1将会指向第二个对象,也就是堆上的对象

问题二:输出结果是true还是false?

String str1 = new String("aa");
 String str2 = "aa";
 System.out.println(str1 == str2);

答案很明显是false,因为两个变量指向的地址不同,一个指向字符串常量池,一个指向堆上的对象,而==比较的就是地址。

问题三:输出结果是true?

String str1 = new String("aa");
 str1.intern();
 String str2 = "aa";
 System.out.println(str1 == str2);

首先我们来了解一下intern方法
intern的处理是 先判断字符串常量是否在字符串常量池中,如果存在直接返回该常量,如果没有找到,说明该字符串常量在堆中,则处理是把堆区该对象的引用加入到字符串常量池中,以后别人拿到的是该字符串常量的引用,实际存在堆中。

也就是说现在字符串常量池中的"aa"实际上是指向堆上的String对象的?所以结果是true?
并不是,结果还是false

回到问题一

String str1 = new String("aa");

这段代码创建了两个对象,而第一个就是在字符串常量池中的,而intern方法在判断时会发现字符串常量池中已经存在"aa"对象了,所以它就不用把字符串常量池中添加一个指向堆上的String对象的地址了
所以最后intern方法只是返回了"aa"对象,并没有做任何修改

所以还是str1指向堆,str2指向字符串常量池,结果为false

问题四:那要怎么样才能true?

String str3 = new String("a") + new String("a");
str3.intern();
String str4 = "aa";
System.out.println(str3 == str4);

这里打印的结果就是true了

这里的str3生成的方式不再是new String(“aa”);
而是new String(“a”) + new String(“a”);拼接起来的方式,因此在编译后,Class文件中的常量池写入的是"a"对象而不是"aa"对象,如下图:

在这里插入图片描述

因此intern方法在判断时会发现字符串常量池中并没有"aa"对象,于是它就把堆中String对象的引用加入到字符串常量池中。
之后创建str4的时候,str4就会先在字符串常量池中先查找有没有"aa",于是它找到了intern放入的引用,并把这个引用赋给str4
所以str3和str4都是同一个引用,str3==str4,为true

问题五:那么这段代码又创建了几个对象?

String str3 = new String("a") + new String("a");

答案是五个

因为使用+号的String字符串拼接,底层其实都是先创建一个StringBuilder对象,然后调用append方法把要+的字符串都append进去,最后toString创建一个新的String对象如下图:

在这里插入图片描述

红色的地方就是new出来对象的语句,而绿色则是两次append
四个红色一共四个对象,再加上字符串常量池上创建的"a"对象,一共五个

这也正是为什么阿里巴巴代码规范中不建议在for循环里使用+号拼接字符串

在这里插入图片描述

String str1 = "aaa";
String str2 = "bbb";
String str4 = str1 + str2;

这个的String str4 = str1 + str2;创建了两个对象,StringBuilder和toString时生成的String对象

那下面这段呢?是"aaa"对象加"bbb"对象加StringBuilder和toString时生成的String对象一共四个对象吗?

String str5 = "aaa" + "bbb";

很可惜这段只创建了1个对象
java编译器在编译这段的时候做了优化,实际上"aaa"+"bbb"会先拼接成"aaabbb"之后才开始编译,也就是说这段代码等于是String str5 = “aaabbb”
如下图:(code里面没有任何new操作)

在这里插入图片描述

到此这篇关于深入理解Java new String()的文章就介绍到这了,更多相关Java new String()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 最简单的MyBatis Plus的多表联接、分页查询实现方法

    最简单的MyBatis Plus的多表联接、分页查询实现方法

    这篇文章主要介绍了最简单的MyBatis Plus的多表联接、分页查询实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • spring、mybatis 配置方式详解(常用两种方式)

    spring、mybatis 配置方式详解(常用两种方式)

    这篇文章给大家总结了常用的两种spring、mybatis 配置方式,本文给大家介绍的非常详细,需要的朋友参考下吧
    2017-12-12
  • SpringBoot静态资源及原理解析

    SpringBoot静态资源及原理解析

    这篇文章主要介绍了SpringBoot静态资源及原理解析,当创建一个jar工程时,想引入css等静态资源时,需要遵守SpringBoot的静态资源映射关系,通过WebMvcAutoConfiguration查看静态配置资源的规则,需要的朋友可以参考下
    2023-12-12
  • 浅谈java二进制、十进制、十六进制、字符串之间的相互转换

    浅谈java二进制、十进制、十六进制、字符串之间的相互转换

    下面小编就为大家带来一篇浅谈二进制、十进制、十六进制、字符串之间的相互转换。小编觉得挺不错的,现在就分享给大家,也给大家做个参考,一起跟随小编过来看看吧
    2016-06-06
  • 使用SpringBoot + Redis + Vue实现动态路由加载页面的示例代码

    使用SpringBoot + Redis + Vue实现动态路由加载页面的示例代

    在现代 Web 应用开发中,动态路由加载能够显著提升应用的灵活性和安全性,本文将深入探讨如何利用 Spring Boot、Redis、Element UI 和 Vue 技术栈实现动态路由加载,并通过 Redis 生成和验证有效链接以实现页面访问控制,需要的朋友可以参考下
    2024-09-09
  • Java实现FTP批量大文件上传下载篇1

    Java实现FTP批量大文件上传下载篇1

    这篇文章主要为大家详细介绍了Java实现FTP批量大文件上传下载的基础篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Springboot 内部服务调用方式

    Springboot 内部服务调用方式

    这篇文章主要介绍了Springboot 内部服务调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 基于Java实现五子棋小游戏(附源码)

    基于Java实现五子棋小游戏(附源码)

    这篇文章主要为大家介绍了如何通过Java实现简单的五子棋游戏,文中的示例代码讲解详细,对我们学习Java游戏开发有一定帮助,需要的可以参考一下
    2022-11-11
  • Java实现获取内网的所有IP地址

    Java实现获取内网的所有IP地址

    这篇文章主要介绍了如何利用Java语言实现获取内网的所有IP地址,文中的示例代码讲解详细,对我们学习有一定的参考价值,快跟随小编一起学习一下吧
    2022-06-06
  • Spring-基于Spring使用自定义注解及Aspect实现数据库切换操作

    Spring-基于Spring使用自定义注解及Aspect实现数据库切换操作

    这篇文章主要介绍了Spring-基于Spring使用自定义注解及Aspect实现数据库切换操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09

最新评论