热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JVM学习笔记:StringBuilder

String的基本特性 String:字符串,用""引起来表示 String 声明为final,不可以被继承 String实现了Serializable

String的基本特性


  • String:字符串,用""引起来表示

  • String 声明为final,不可以被继承

  • String实现了Serializable接口,表示字符串时支持序列化的

  • String实现了Comparable接口,表示String可以比较大小

  • JDK8之前用char[]存储字符串数据,JDK9改为byte[]

  • String代表不可变得字符序列

字符串常量池中是不会存储相同内容的字符串的

  • String的 String Pool是一个固定大小的Hashtable,默认大小长度是1009.

  • 使用-xx:stringTableSize可设置StringTable的长度

  • JDK8中StringTable默认长度改为60013,1009是可设置的最小值


String的内存分配

常量池类似于一个Java系统级别提供的缓存,8种基本数据类型的常量池都是系统协调的。

对于特殊的String类型的常量池:

  1. 直接使用双引号声明出来的String对象会直接存储在常量池中

  2. 如果不是用""声明的String对象,可以使用String提供的intern()方法

Java6,字符串常量池放在永久代

Java7,将字符串常量池位置调整到了堆空间中

Java8,虽然去掉了永久代改为元空间,但是字符串常量还在在堆中

String的基本操作


字符串拼接操作


  1. 常量与常量的拼接结果在常量池,原理是编译期优化

  2. 常量池中不会存在相同的常量

  3. 只要其中有一个是变量结果就在堆里面

  4. 如果拼接使用intern()方法则主动将常量池中还没有的字符串对象放入池中,并返回对象地址

intern():判断字符串常量池中是否存在javaEEhadoop值,若存在则返回常量池中的地址,若字符串常量池中不存在,则在常量池中加载一份javaEEhadoop,并返回对象的地址

只要String拼接的连接符两边出现了变量就会new StringBuilder

String s1="a";
String s2="b";
String s3=s1+s2;
"s1+s2"的执行细节:StringBuilder s =new StringBuilder();s.append("a");s.append("b");s.toString();

StringBuilder的append()方法添加字符串的效率要远远高于直接String字符串拼接

因为append()方法自始至终只会创建一个StringBuilder对象

StringBuilder s =new StringBuilder();
for(int i&#61;0;i<10;i&#43;&#43;){s.append("a");
}

在实际开发中若能确定前后添加的字符串长度不高于某个限定值highlevel&#xff0c;建议使用构造器

StringBuilder s &#61; new StringBuilder(highlevel)

intern()的使用

若在任意字符串上调用String.intern方法&#xff0c;那么其返回结果所指向的那个类实例&#xff0c;必须和直接以常量形式出现的字符串实例完全相同。所以

("a"&#43;"b"&#43;"c").intern()&#61;&#61;"abc" //true

Interned 就是确保字符串在内存里只有一份拷贝&#xff0c;节约内存空间

如何确保变量s指向的是字符串常量池中的数据

1. String s &#61;"snhstart";
2. String s &#61; new String ("snhstart").intern();

new String("ab")会创建几个对象 &#xff1f;  //2个一个对象是new关键字&#xff0c;在堆空间创建的一个对象是字符串常量池中的对象&#xff0c;字节码指令&#xff1a;ldc

String str &#61; new String("a")&#43;new String("b")  //对象1&#xff1a;new StringBuilder()对象2&#xff1a;new String("a")对象3&#xff1a;常量池中的"a"对象4&#xff1a;new String("b")对象5&#xff1a;常量池中的"b"toString()的调用在字符串常量池中&#xff0c;没有生成"ab"

String s&#61;new String ("1")
String s1 &#61; "1"
system.out.println(s&#61;&#61;s1);//false
s是堆空间中new的地址&#xff0c;s1是字符串常量池中"1"的地址String s2 &#61; new String("1")&#43;new String("1")
//s2变量记录的地址为&#xff1a;new String("11")的地址&#xff0c;此行代码后字符串常量池中没有生成"11"
s2.intern();//在字符串常量池中生产"11"
/*在jdk6中创建了一个新的对象&#xff0c;有新的地址
在jdk7中常量池中并没有创建“11”&#xff0c;而是创建了一个指向堆空间“11”的地址
因为7以后&#xff0c;字符串常量池放入堆空间&#xff0c;那么intern判断已经new了一个“11”就不在在字符串常量池中创一个“11”&#xff0c;而是创一个指向new “11”地址指针&#xff0c;所s3虽然是常量池中的“11”但是实际就是new的s2的地址
*/
String s3&#61;"11";
system.oout.println(s2&#61;&#61;s3);//jdk6:false,jdk7:true

G1的String去重操作

去底层new的char型数组的的重复的操作&#xff0c;并非常量池的

  • 当垃圾收集器工作的时候回访问堆上存活的对象。对每一个访问的对象都会检查是否候选的要去重的对象

  • 如果是&#xff0c;把这个对象的一个引用插入到队列中等待后续的处理。一个去重的线程在后台运行&#xff0c;处理这个队列&#xff1a;从队列删除这个元素&#xff0c;然后尝试去重它引用的String对象

  • 使用hashtable来记录所有的被String对象使用的不重复的char数组&#xff0c;去重时差这个hashtable来看堆上是否已经存在一个一模一样的char数组

  • 如果存在String对象会被调整引用那个数组&#xff0c;释放原来数组的引用&#xff0c;最终被垃圾收集器回收掉

  • 如果查找失败&#xff0c;char数组会被插入到hashtable&#xff0c;这样以后就可以共享这个数组


推荐阅读
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 传统上,Java 的 String 类一直使用 char 数组来存储字符数据。然而,在 Java 9 及更高版本中,String 类的内部实现改为使用 byte 数组。本文将探讨这一变化的原因及其带来的好处。 ... [详细]
  • iOS 不定参数 详解 ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
  • 题目描述:牛客网新员工Fish每天早上都会拿着一本英文杂志,在本子上写下一些句子。他的同事Cat对这些句子非常感兴趣,但发现这些句子的单词顺序被反转了。例如,“student. a am I”实际上是“I am a student.”。Cat请求你帮助他恢复这些句子的正常顺序。 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本文介绍了如何在 Spring Boot 项目中使用 spring-boot-starter-quartz 组件实现定时任务,并将 cron 表达式存储在数据库中,以便动态调整任务执行频率。 ... [详细]
  • malloc 是 C 语言中的一个标准库函数,全称为 memory allocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • C语言中全部可用的数学函数有哪些?2.longlabs(longn);求长整型数的绝对值。3.doublefabs(doublex);求实数的绝对值。4.doublefloor(d ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文介绍如何使用线段树解决洛谷 P1531 我讨厌它问题,重点在于单点更新和区间查询最大值。 ... [详细]
author-avatar
靳淑怡心淑怡綺
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有