文章目录

  • 一、字符串常量池
  • 二、字符串的不可变性
  • 三、字符串修改
  • 四、StringBuilder与StringBuffer的方法
  • 四、StringBuilder与StringBuffer区别

一、字符串常量池

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);}

上面两种创建String对象的方式相同吗?

在Java程序中,“ ”双引号引起来的字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。

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);}

intern()方法是将s1中的引用放入常量池中.当s2创建时,就会指向常量池的那个引用.

二、字符串的不可变性

String是一种不可变对象. 字符串中的内容是不可改变。
String的源码中,注解中写到String是一个常量,不可修改.

我们在来看String类型是如何存储字符串的

可能有人说因为被final修饰,所以不能修改,首先这是一个很大的误区,final修饰只能说明value引用的对象不能修改,而不是说value引用的值不能修改.

我们随便打开一个String的方法,这里打开的是toUpperCase方法,可以发现:所有涉及到修改字符串内容的方法都是创建一个新对象返回.
String为什么要设计成不可变的?

  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个

字符串常量池与StringBuilder相关推荐

  1. String类菜鸟级教程(字符串常量池及不可变,StringBuffer 和 StringBuilder)

    文章目录 前言 1.创建字符串 2.字符串比较相等 2.1字符串传参 3.字符串常量池 4.字符串创建实例分析 5.理解字符串不可变 6.字符, 字节与字符串 6.1字符与字符串 6.2字节与字符串 ...

  2. String为什么是不可变的?为什么要有字符串常量池?String和StringBuilder和StringBuffer

    String的相关知识点 1. 不可变字符串String类对象 2. String不可变的好处 3.字符串常量池 4. String.StringBuilder和StringBuffer 1. 不可变 ...

  3. JVM---StringTable(字符串常量池)

    StringTable(字符串常量池) 字符串常量池 StringTable(字符串常量池) String的基本特性 String 的底层结构 String 的内存分配 String 的基本操作 字符 ...

  4. JVM - 深入剖析字符串常量池

    文章目录 字符串常量池 位置的变更 JVM对字符串常量池的优化 字符串的常见创建方式 (1.7+) 直接赋值字符串 new String() intern 经典面试题 下列代码创建几个对象 案例 案例 ...

  5. JVM_04 字符串常量池(详解intern( ))

    一.String的基本特性 String:字符串,使用一对""引起来表示. String sl = "hello"://字面量的定义方式 String s2 = ...

  6. 常量池之字符串常量池String.intern()

    运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...

  7. 字符串常量池StringTable 你真的了解么

    本篇目录 1. String的基本特性 2. String的内存分配 3. 字符串拼接操作 3.1 字符串拼接 3.2 拼接操作与append的效率对比 4. intern()的使用 4.1 new ...

  8. java字符串常量池长度_Java String类相关知识梳理(含字符串常量池(String Pool)知识)...

    目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...

  9. 一文彻底搞懂字符串、字符串常量池原理

    文章目录 1. 常量池概述 1.1 静态常量池.运行时常量池与字符串常量池的区别 2. 字符串常量池的设计初衷 3. 字符串的几种创建方式及原理 ①:直接赋值 ②:new String() ③:int ...

最新文章

  1. 通过电机编码器AB相输出确定电机转向
  2. 运行 命令 linux,Linux基本命令运行
  3. 怎样学习(3):迭代学习,精益求精
  4. c++ stl队列初始化_创建一个向量,并将其像C ++ STL中的数组一样初始化
  5. Java代码的编译与反编译那些事儿
  6. css首行缩进2个字符
  7. flutter release 版本 调试_腾讯课堂Flutter工程实践系列——接入篇
  8. 机器学习算法-详细白板推导系列视频
  9. 移动iptv安装三方软件
  10. 【转】Excel表格的35招必学秘技
  11. cis系统服务器,基于客户端/服务器模式头影测量信息系统(CIS)影像测量模块的开发...
  12. ros nh.parmam 用法
  13. 射频识别(RFID)
  14. svg的学习笔记《一》:如何使用svg sprite
  15. 山西民生云认证工资_山西民生云养老资格认证手机版-山西民生云社会保险综合服务平台v2.2 最新版-007游戏网...
  16. VS2015 解决 “有太多的错误导致IntelliSense引擎无法正常工作,其中有些错误无法在编辑其中查看”问题
  17. OpenMeetings(3)----启动顺序解析
  18. SAP 创建可选BOM的BAPI
  19. php如何删除文件夹里的图片,php如何删除文件夹
  20. Nervos 社区伙伴成功破解最新海报谜题

热门文章

  1. UML图:类图 --详细介绍
  2. 不同显卡(GPU)浮点数计算能力
  3. python requests爬虫——爬取李开复博客信息(包括javascript部分信息)
  4. 李开复:在哪里创业与怎么创业
  5. 我!程序媛!上家阿里巴巴,下家字节跳动!薪资翻番!选择裸辞躺平!无限期休息!
  6. 【Python百日进阶-Web开发-Linux】Day231 - 真机安装Ubuntu桌面版、搜狗拼音输入法、Python开发环境
  7. 7 种回归方法!请务必掌握!
  8. Cesium教程(十四):简易三维模型的可视化
  9. 复古拼贴_如何在Android上使用Google相册创建拼贴,动画或电影
  10. 【USB设备设计】-- CDC 设备开发(虚拟串口设备)