字符串常量池与StringBuilder

字符串常量池与StringBuilderintern 是一个 native 方法 Native 方法指 底层使用 C 实现的 看不到其实现的源代码 该方法的作用是手动将创建的 String 对象添加到常量池中 可能有人说因为被 final 修饰 所以不能修改 首先这是一个很大的误区 final 修饰只能说明 value 引用的对象不能修改 而不是说 value 引用的值不能修改 我们随便打开一个 String 的方法 这里打开的是 toUpperCase 方法 可以发现 所有涉及到修改字符串内容的方法都是创建一个新对象返回 之前常量池没有存储过任何字符串

在这里插入图片描述

一、字符串常量池

public static void main(String[] args) { 
    String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s3 == s4); } 

1.使用字符常量直接赋值:

public static void main(String[] args) { 
    String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); } 

在这里插入图片描述
在直接用字面常量赋值String时,先在常量池里找,是否有这个字符串,如果没有则创建,我们发现常量池并没有abc,所以我们创建一个“abc”。
在这里插入图片描述
当第二次创建”abc”字符串赋给s2时直接指向就行.
在这里插入图片描述
s1和s2指向的是同一块引用,所以s1 == s2。
2.通过new创建String类对象:
在这里插入图片描述
只要new对象,它的引用就是唯一的.
使用常量串创建String类型对象的效率更高,而且更节省空间。
3.intern方法:
intern 是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中。






















public static void main(String[] args) { 
    char[] ch = new char[]{ 
   'a','b','c'}; String s1 = new String(ch); String s2 = "abc"; System.out.println(s1 == s2); } 

在这里插入图片描述
我们可见s1 和 s2指向不同的引用

public static void main(String[] args) { 
    char[] ch = new char[]{ 
   'a','b','c'}; String s1 = new String(ch); s1.intern(); String s2 = "abc"; System.out.println(s1 == s2); } 

二、字符串的不可变性

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.

三、字符串修改

字符串是不能修改的,每次修改都会创建新对象,效率非常低下.

public static void main(String[] args) { 
    String str = "wo"+"yao"+"jin"+"da"+"chang"; System.out.println(str); } 

在这里插入图片描述
当然是可以正常输出的,我们看一下汇编.
在这里插入图片描述
我们会发现创建了许多StringBuilder对象,去拼接字符串,这样效率十分低下。






public static void main(String[] args) { 
    long start = System.currentTimeMillis(); String s = ""; for(int i = 0; i < 10000; ++i){ 
    s += i; } long end = System.currentTimeMillis(); System.out.println(end - start); start = System.currentTimeMillis(); StringBuffer sbf = new StringBuffer(""); for(int i = 0; i < 10000; ++i){ 
    sbf.append(i); } end = System.currentTimeMillis(); System.out.println(end - start); start = System.currentTimeMillis(); StringBuilder sbd = new StringBuilder(); for(int i = 0; i < 10000; ++i){ 
    sbd.append(i); } end = System.currentTimeMillis(); System.out.println(end - start); } 

在这里插入图片描述
我们发现在对String进行修改时,String与StringBuffer和StringBuilder相差几百倍.

四、StringBuilder与StringBuffer的方法

在这里插入图片描述
这里都是StringBuffer和StringBuilder的一些方法.
1.append
拼接字符串






public static void main(String[] args) { 
    StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("wo yao jin da chang!"); System.out.println(stringBuilder); } 

在这里插入图片描述
2.reverse
字符串逆置




public static void main(String[] args) { 
    StringBuilder stringBuilder = new StringBuilder("abcd"); stringBuilder.reverse(); System.out.println(stringBuilder); } 

在这里插入图片描述
3.delete
删除指定范围内的字符




public static void main(String[] args) { 
    StringBuilder stringBuilder = new StringBuilder("abcd"); stringBuilder.delete(0,2); System.out.println(stringBuilder); } 

在这里插入图片描述
String与StringBuilder相互转换:
String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可
以修改。频繁修改字符串的情况考虑使用StringBuilder
1.String变为StringBuilder








public static void main(String[] args) { 
    //调用StringBuilder构造方法 String str = "abc"; StringBuilder stringBuilder = new StringBuilder(str); } 
 public static void main(String[] args) { 
    //append拼接字符串 String str = "abc"; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(str); System.out.println(stringBuilder); } 

在这里插入图片描述
1.StringBuilder变为String
在这里插入图片描述
我们可以看一下StringBuilder的toString()方法返回的是一个String对象.






public static void main(String[] args) { 
    //StringBuilder的toString()方法 StringBuilder stringBuilder = new StringBuilder("abc"); String str = stringBuilder.toString(); System.out.println(str); } 

在这里插入图片描述

四、StringBuilder与StringBuffer区别

String、StringBuffer、StringBuilder的区别:
1.String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
2.StringBuffer与StringBuilder大部分功能是相似的
3.StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
在这里插入图片描述
StringBuffer中的每个方法加入了synchronized,它就相当于是一把锁,只要有第一个人访问这个方法,那么这个方法就只能等第一个人访问完成之后,剩下的人才能访问.










String str = new String("abc"); String str = new String("ab") + new String("c"); 

这项行代码分别创建多少个对象?(之前常量池没有存储过任何字符串)

  1. 2个
  2. 6个
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216391.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午11:57
下一篇 2026年3月18日 上午11:57


相关推荐

  • rpm 完全卸载mysql

    rpm 完全卸载mysql一、查看当前mysql安装情况:rpm-qa|grep-imysql二、删除之前安装的mysqlrpm-evmysql-community-libs-8.0.11-1.el7.x86_64如果报依赖错误,就使用下面的命令rpm-evmysql-community-libs-compat-8.0.11-1.el7.x86_64–nodeps三、查找之前mysql的目录,都删掉fin…

    2026年2月12日
    4
  • 【原创】PEST分析思维的一些基本思考与见解

    【原创】PEST分析思维的一些基本思考与见解数据说·思维季所谓不可能,只是现在的自己不可能,对将来的自己而言那是“可能”的。–稻盛和夫前言我们上篇内容,梳理和分享数据分析入门级思维—描述性分析思维,能让我们了解到数据信息的整体概况…

    2022年5月15日
    52
  • python基本语法结构

    python基本语法结构python 基本语法结构目录 1 0 变量 2 0 数据类型 3 0 类型转换 4 0 字符串结语目录 1 0 变量在 Python 中 当你给它赋值时就会创建变量 Python 没有用于声明变量的命令 变量在第一次为其赋值时创建 和 matlab 一样 2 0 数据类型 List 列表是一个有序且可变的集合 允许重复成员 turple 元组是一个有序且不可更改的集合 允许重复成员 Set 集合是一个无序且无索引的集合 没有重复的成员 dict 字典是一个有序 且可变的集合 没有重复的成员 从 Python

    2026年3月16日
    2
  • 地形分析的主要内容(流浪地球的特效水平)

    早期的天龙八部跟武侠世界基本相似。先简单地说一下载入场景的大致过程:     读取.Scene文件     根据读取.Terrain文件     读取地砖大小()地形大小(,),缩放值()。     读取所有要用的地形贴图(中各项)。     读取.g

    2022年4月15日
    51
  • 安卓7.1精简版下载_asm字节码

    安卓7.1精简版下载_asm字节码ASM 7.1 发布

    2022年4月21日
    223
  • 异步编程中的BeginInvoke和EndInvoke

    异步编程中的BeginInvoke和EndInvoke如果委托对象的调用列表中只有一个方法 引用方法 就可以异步执行这个方法 通过调用委托类特有的两个方法 BeginInvoke 和 EndInvoke 去执行 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp BeginInvoke 和 EndInvoke nbsp 的三种模式 nbsp BeginInvoke 方法的参数列表 nbsp 1 引用方法所需要的参数 nbsp nbsp 2 两个额外的参数 callback 参数和 state 参数 nbsp

    2025年11月12日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号