Java字符串常量池示例详解
作者:FhToday 发布时间:2021-10-11 10:55:02
为什么会有常量池的概念?
不知道小伙伴们是否有思考过这个问题? 没有思考也无所谓,小编在这里类比一下,大家就会清晰了。什么是池? 我们听的最多的池,应该是数据库连接池. 为什么会有数据库连接池,其实就是为了节省资源,提高性能,防止重复创建连接,避免占用内存和网络资源。
常量池其实就是跟数据库连接池的目的都是一样的。那么他是如何实现的呢? 因为常量池是JVM的概念,源码我们也不好看,所以我们还以连接池来类比。
池化的目标就是缓存和管理
稍微提一点池化的概念,其实就是对资源做一个包装,在包装层来加一些对这个资源的属性信息,比如使用次数,最后操作时间,最长生命周期一样。然后通过后台线程对资源包装层的扫描,来对真实资源的做一个管理。Google的Guava的Cache就是这么做的,我们自己也可以利用 common-pool2 工具包自己来做,或者说池化。
Java字符串常量池
在 JDK 1.7 之前,HotSpot 虚拟机中的字符串常量池都在方法区中,用永生代实现。JDK 1.7 及以后的版本,字符串常量池移到了堆里。
JDK 1.6 的 String.intern 方法会将首次遇到的 String 对象复制到永久代,并返回这个对象的引用。
JDK 1.7 的 String.intern 方法不再复制,而是记录首次出现的 String 对象的引用。
以下用 JDK 1.8 实验探究字符串常量池。
// test1
String s1 = "red";
String s2 = "red";
System.out.println(s1 == s2); // true
// test2
String s3 = new String("red");
String s4 = new String("red");
System.out.println(s3 == s4); // false
// test3
System.out.println(s1 == s3); // false
// test4
System.out.println(s3.intern() == s1); // true
System.out.println(s3.intern() == s3); // false
System.out.println(s3.intern() == s4); // false
// test5
String s5 = new String("thunder");
String s6 = s5.intern();
String s7 = "thunder";
System.out.println(s5 == s6); // false
System.out.println(s6 == s7); // true
// test6
String s8 = new String("1") + new String("1");
// String s8 = new StringBuilder().append().toString()
String s9 = s8.intern();
String s10 = "11";
System.out.println(s8 == s9); // true
System.out.println(s9 == s10); // true
常量池可以看作是一个集合,没有重复的元素。用双引号创建的对象直接放到常量池,new 一定会在堆中创建一个新的对象,如果常量池没有值相同的对象那么会在常量池也创建一个对象。intern 的作用是判断常量池是否包含值相同的字符串,是则返回这个字符串对象的引用,否则将当前实例的引用放到常量池并返回当前实例的引用。
另外,字符串的拼接实际上是用了 StringBuilder,所以字符串 s8 的创建会伴随以下对象的创建:
堆中两个不同的 String 对象 1
字符串常量池中一个 String 对象 1
一个 StringBuilder 对象
堆中的 String 对象 11
由于 s8 的创建方式不是 new String 而是拼接,所以不会在常量池中创建值为“11”的对象,这也是 test5 和 test6 要对比的问题。
总结
来源:https://juejin.cn/post/6989609445785337870


猜你喜欢
- Android IPC机制Messenger实例详解前言:Messenger可以翻译成信使,通过它可以在不同进程间传递Message对象有了
- 目录如何实现简化呢?当然,一些常见的方法已经封装在了 Norns.Urd.Extensions.Polly如何启用 Norns.Urd +
- 快捷键是很多软件的常用功能,本文实例讲解了三种方法来实现C# button快捷键,如Alt + *(按钮快捷键),Ctrl+*及其他组合键等
- 静态变量静态变量位于栈上,它是一个全局变量,在编译期就已经生成。public class Cow{public static int cou
- AnyChat(全名叫Anychat SDK),也叫音视频互动开发平台;是一套跨平台的即时通讯解决方案,基于先进的H.264视频编码标准、A
- 一、使用方法查找DLL文件,通过Reflection反射类库里的各种方法来操作dll文件二、步骤加载DLL文件Assembly assemb
- 一直以来,我们都是在服务端查询出结果生成JSON字符串,供前端调用,那么我们能否把从前端接受的JSON字符串转换成字典集合,让后台处理呢?比
- 本文实例为大家分享了java数独游戏的具体代码,供大家参考,具体内容如下自己写的数独游戏,共9关,代码如下:1、DoShudu类用于产生数独
- Android 2.3提供一个称为严苛模式StrictMode的调试特性,Google称该特性已经使数百个Android上的Google应用
- annotation就是注解的意思,在我们使用的 * 时,可以通过业务层添加的某个注解,对业务方法进行拦截,之前我们在进行统一方法拦截时使用
- public void PrintPercentage(int FinishedCount, int TotalCount) {
- 有时候一些项目并不需要提供 Web 服务,例如跑定时任务的项目,如果都按照 Web 项目启动未免画蛇添足浪费资源为了达到非 Web 运行的效
- 返回值转成JSONString的处理主要需求描述有些返回值中的null需要转换成“”或[],另外有些
- 目录目标功能点准备工作引入 Maven 依赖配置 DAO 数据层创建 JWT 工具类登录LoginFilterLoginSuccessHan
- 一. Window 分类应用 Window(ApplicationWindow: 对应一个 Acitivity)
- 这篇文章主要介绍了Java日期与时间类原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参
- Spring Boot中可以在配置文件中直接进行数据库配置,spring.datasource.username= rootspring.d
- 一、Maven简介1. 什么是MavenMaven:是Apache提供的免费开源的项目管理工具。它提供了一个项目对象模型(pom.xml)、
- 什么是自动填充有些表中会有更新时间、创建时间、更新人或者创建人这些字段。每次对数据进行新增、删除、修改时都需要对这些字段进行设置。传统的做法
- 用户关闭软件时,软件一般会给“是否确认关闭”的提示。通常,我们把它写在FormClosing 事件中,如果确定关闭,就关闭;否则把FormC