返回顶部
首页 > 资讯 > 精选 >如何理解Java 虚拟机中的String 类和常量池
  • 721
分享到

如何理解Java 虚拟机中的String 类和常量池

2023-06-05 04:06:07 721人浏览 薄情痞子
摘要

本篇文章为大家展示了如何理解Java 虚拟机中的String 类和常量池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、String 对象的两种创建方式String str1 

本篇文章为大家展示了如何理解Java 虚拟机中的String 类和常量池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

一、String 对象的两种创建方式

String str1 = "abcd";String str2 = new String("abcd");System.out.println(str1==str2); //false

这两种不同的创建方法是有差别的:

第一种方式是在常量池中获取对象(“abcd” 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象);

第二种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 “abcd” 字符串对象)。

  • “abcd” 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,该字符串对象指向这个 “abcd” 字符串字面量;

  • 使用 new 的方式会在堆中创建一个字符串对象。
    str1 指向常量池中的 “abcd”,而 str2 指向堆中的字符串对象。

二、intern() 方法

intern() 方法设计的初衷,就是重用 String 对象,以节省内存消耗。

jdk6:当调用intern方法的时候,如果字符串常量池先前已创建出该字符串对象,则返回常量池中的该字符串的引用。否则,将此字符串对象添加到字符串常量池中,并且返回该字符串对象的引用。

JDK6+:当调用intern方法的时候,如果字符串常量池先前已创建出该字符串对象,则返回常量池中的该字符串的引用。否则,如果该字符串对象已存在与Java堆中,则将堆中对此对象的引用添加到字符串常量池中,并且返回该引用;如果堆中不存在,则在常量池中创建该字符串并返回其引用。

JVM 运行时数据区中的方法区有一个常量池,但是发现在 JDK 1.6 以后常量池被放置在了堆空间,因此常量池位置的不同影响到了 String 的 intern() 方法的表现。

String s = new String("1");s.intern();String s2 = "1";System.out.println(s == s2);String s3 = new String("1") + new String("1");s3.intern();String s4 = "11";System.out.println(s3 == s4);

JDK 1.6 及以下

上述代码输出结果:

falsefalse

解释:
在 JDK 1.6 中所有的输出结果都是 false,因为 JDK 1.6 以及以前版本中,常量池是放在 PermGen 区(属于方法区)中的,而方法区和堆区是完全分开的。

使用引号声明的字符串会直接在字符串常量池中生成的,而 new 出来的 String 对象是放在堆空间中的。所以两者的内存地址肯定是不相同的,即使调用了 intern() 方法也是不影响的。

intern() 方法在 JDK 1.6 中的作用:比如 String s = new String(“1”);,再调用 s.intern(),此时返回值还是字符串”1”,表面上看起来好像这个方法没什么用处。但实际上,在 JDK1.6 中:检查字符串常量池里是否存在 “1” 这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把 “1” 添加到字符串常量池中,然后再返回它的引用。

JDK 1.6 及以上

上述代码输出结果:

falsetrue

解释:
String s= new String("1") 生成了字符串常量池中的 “1” 和堆空间中的字符串对象。

s.intern() s对象去字符串常量池中寻找后,发现 “1” 已存在于常量池中。

String s2 = "1"生成 s2 的引用指向常量池中的 “1” 对象。

显然,s 和 s2 的引用地址是不同的。

String s3 = new String("1") + new String("1")在字符串常量池中生成 “1”,并在堆空间中生成 s3 引用指向的对象(内容为 “11”)。 注意此时常量池中是没有 “11” 对象。

s3.intern()将 s3 中的 “11” 字符串放入字符串常量池中。 JDK 1.6 的做法是直接在常量池中生成一个 “11” 的对象。但在 JDK 1.7 中,常量池中不需要再存储一份对象了,可以直接存储堆中的引用。这份引用直接指向 s3 引用的对象,也就是说 s3.intern() == s3 会返回 true。

String s4 = "11", 这一行代码会直接去常量池中创建,但是发现已经有这个对象了,此时 s4 就是指向 s3 引用对象的一个引用。因此 s3 == s4 返回了true。

三、字符串拼接

String str1 = "str";String str2 = "ing";String str3 = "str" + "ing";//常量池中的对象String str4 = str1 + str2; //TODO:在堆上创建的新的对象      String str5 = "string";//常量池中的对象System.out.println(str3 == str4);//falseSystem.out.println(str3 == str5);//trueSystem.out.println(str4 == str5);//false

注意:尽量避免多个字符串拼接,因为这样会重新创建对象。 如果需要改变字符串的话,可以使用 StringBuilder 或者 StringBuffer。

面试题:String s1 = new String(“abc”);问创建了几个对象?

创建2个字符串对象(前提是 String Pool 中还没有 “abcd” 字符串对象)。

  • “abc” 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,指向这个 “abcd” 字符串字面量;

  • 使用 new 的方式会在堆中创建一个字符串对象。
    (字符串常量”abc”在编译期就已经确定放入常量池,而 Java 堆上的”abc”是在运行期初始化阶段才确定)。

String s1 = new String("abc");// 堆内存的地址值String s2 = "abc";System.out.println(s1 == s2);// 输出false//因为一个是堆内存,一个是常量池的内存,故两者是不同的。System.out.println(s1.equals(s2));// 输出true

上述内容就是如何理解Java 虚拟机中的String 类和常量池,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网精选频道。

--结束END--

本文标题: 如何理解Java 虚拟机中的String 类和常量池

本文链接: https://lsjlt.com/news/241063.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何理解Java 虚拟机中的String 类和常量池
    本篇文章为大家展示了如何理解Java 虚拟机中的String 类和常量池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、String 对象的两种创建方式String str1 ...
    99+
    2023-06-05
  • 详解Java 虚拟机(第④篇)——8 种基本类型的包装类和常量池
    Java 基本类型的包装类的大部分都实现了常量池技术, 即Byte,Short,Integer,Long,Character,Boolean; 这 5 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据, 但是超出此范围仍然...
    99+
    2023-06-05
  • Java String类的理解及字符串常量池介绍
    目录一. String类简介1. 介绍2. 字符串构造二. 字符串常量池(StringTable)1. 思考?2. 介绍和分析3. intern方法三. 面试题:String类中两种...
    99+
    2024-04-02
  • 如何理解Java 虚拟机中HotSpot 虚拟机对象
    今天就跟大家聊聊有关如何理解Java 虚拟机中HotSpot 虚拟机对象,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、对象的创建对象的创建步骤:1. 类加载检查虚拟机遇到一条 n...
    99+
    2023-06-05
  • java中String源码和String常量池的示例分析
    小编给大家分享一下java中String源码和String常量池的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!String 常量池分析常用方法equal...
    99+
    2023-05-30
    java string
  • Java中的堆、栈和常量池怎么理解
    这篇文章主要讲解了“Java中的堆、栈和常量池怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的堆、栈和常量池怎么理解”吧!1.寄存器最快的存储区, 由编译器根据需求进行分配...
    99+
    2023-06-17
  • 如何理解JAVA虚拟主机
    今天就跟大家聊聊有关如何理解JAVA虚拟主机,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。其实虚拟主机也可以称之为网站空间,就是把一台运行在互联网上的物理服务器,划分为多个虚拟服务器...
    99+
    2023-06-07
  • 如何深入理解Java虚拟机JVM类加载初始化
    如何深入理解Java虚拟机JVM类加载初始化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 Classloader的作用,概括来说就是将编译后的class装载、...
    99+
    2023-06-17
  • OpenStack中如何部署和管理虚拟机
    在OpenStack中部署和管理虚拟机通常包括以下步骤: 创建虚拟机镜像:首先需要准备一个虚拟机镜像,其中包含操作系统和所需软件...
    99+
    2024-04-09
    OpenStack
  • 如何理解Java常见知识点中的线程池
    这期内容当中小编将会给大家带来有关如何理解Java常见知识点中的线程池,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。线程池的基本思想是一种对象池,在程序启动时就开辟一块内存空间,里面存放了众多(未死亡)的...
    99+
    2023-06-05
  • 如何理解JavaAPI中的String类
    如何理解JavaAPI中的String类,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。JavaAPI之String类[size=10.5000pt]一、所属包java.lang...
    99+
    2023-06-02
  • 如何解析Java虚拟机的Class文件
    这篇文章给大家介绍如何解析Java虚拟机的Class文件,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前面发了几篇学习笔记,但是看这些东西总是感觉很"玄乎",来一篇实战的东西来揭一下"JV...
    99+
    2023-06-17
  • 如何理解Java虚拟机运行时数据区域
    这期内容当中小编将会给大家带来有关如何理解Java虚拟机运行时数据区域,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、程序计数器(Program Counter Register)当前线程所执行的字节码...
    99+
    2023-06-05
  • Java虚拟机中的双亲委派机制怎么理解
    Java虚拟机中的双亲委派机制怎么理解,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类...
    99+
    2023-06-22
  • 如何理解Python虚拟机中的Python运行环境
    今天就跟大家聊聊有关如何理解Python虚拟机中的Python运行环境,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。其实Python运行环境是一个全局性的概念,而执行环境实际就是一个...
    99+
    2023-06-17
  • 如何在VirtualBox中设置虚拟机的磁盘类型
    在VirtualBox中设置虚拟机的磁盘类型,可以通过以下步骤实现: 打开VirtualBox并选择要设置的虚拟机。 点击“设置”按钮打开虚拟机设置窗口。 在左侧菜单中选择“存储”选项卡。 在存储设备列表中找到要设置的磁盘,通常是一个虚拟...
    99+
    2024-06-11
    virtualbox
  • Java Hibernate中的连接池该如何理解
    本篇文章为大家展示了Java Hibernate中的连接池该如何理解,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以...
    99+
    2023-06-17
  • 如何解决虚拟机声音播放异常的问题
    解决虚拟机声音播放异常问题的方法如下: 确保虚拟机中的操作系统已正确安装声卡驱动程序,可以在设备管理器中检查声卡驱动程序是否正常工作。 检查虚拟机设置中的声音选项,确保声音设备已正确配置并启用。 如果虚拟机中的声音播放异常,尝试...
    99+
    2024-06-10
    virtualbox
  • 如何理解Java虚拟机及JVM体系结构是什么
    今天就跟大家聊聊有关如何理解Java虚拟机及JVM体系结构是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。JVM(Java 虚拟机)Java虚拟机,java源文件(.java)通...
    99+
    2023-06-17
  • 一文带你了解如何正确使用Java中的字符串常量池
    目录前言理解字符串常量池两种创建字符串方式字符串拼接方式妙用String.intern() 方法字符串常量池有多大字符串常量池的优缺点总结前言 研究表明,Java堆中对象占据最大比重...
    99+
    2022-12-26
    Java字符串常量池使用 Java字符串常量池
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作