栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java——String类的详解(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java——String类的详解(二)

Java——String类的详解(二)
  • 字符串常量池
    • 什么是常量池
    • String对象的创建
      • 直接引用字符串
      • 使用new创建
      • intern方法
      • String创建方法的区别
  • 字符串的不可变性
    • 为什么String类要设计为不可修改的
  • StringBuilder和StringBuffer
    • String,StringBuffer,StringBuilder的区别

字符串常量池 什么是常量池
public static void main(String[] args) {
	String s1 = "hello";
	String s2 = "hello";
	String s3 = new String("hello");
	String s4 = new String("hello");
	
	System.out.println(s1 == s2); // true
	System.out.println(s1 == s3); // false
	System.out.println(s3 == s4); // false
}

通过之前的知识可以知道s1和s2引用的是同一个对象,而s3和s4不是,但是为什么会这样呢。

在Java中,由于有些数字和字符,字符串需要被频繁的调用,为了更快的运行速度,更节省的内存,Java为基本数据类型和String类提供了常量池,这样的话只要再次调用同样的内容,编译器不会再创建新的内容,而是去常量池拿出上一次创建的内容。

Java中有以下的池:
1.Class文件常量池:每个.Java源文件编译后生成.Class文件中会保存当前类中的字面常量以及符号信息
2. 运行时常量池:在.Class文件被加载时,.Class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份
3. 字符串常量池

String对象的创建 直接引用字符串
String s1 = "hello";

当使用上面这种方法创建字符串时,在字节码文件加载时,hello就保存在了字符串常量池中,创建时,先在字符串常量池中寻找,找到了就把其引用赋值给s1

使用new创建
String s2 = new String("hello");

以下过程了解即可:

  1. 当用new创建字符串对象时,先在堆上开辟String对象的空间,并把其成员初始化为0,然后将空间首地址压栈。

  2. 将String对象的首地址拷贝一份到栈顶备用

  3. 将常量池中的hello字符串引用拷贝到栈顶

  4. 调用String的构造方法,此时取走栈顶的hello的引用和String的地址

  5. 用栈顶的元素给s2赋值

总结:
只要用new创建对象,都是唯一的,地址肯定时不一样的
使用常量串创建对象的效率高,占用空间小。

intern方法

手动将创建的字符串常量入池

public static void main(String[] args) {
	char[] ch = new char[]{'a', 'b', 'c'};
	String s1 = new String(ch); // s1对象并不在常量池中
	
	//s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中
	
	String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
	System.out.println(s1 == s2);
}

本来是输出false,但是将注释取消掉,就会输出true

String创建方法的区别
  1. String str = “hello”
    只会开辟一块堆内存空间,保存在字符串常量池中,然后str共享常量池中的String对象

  2. String str = new String(“hello”)
    会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟的String对象赋值。

  3. String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’})
    现在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中

字符串的不可变性
  1. String类被final修饰,表明该类不能被继承
  2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。

因此,所有修改字符串的方法都是创建一个新的字符串

为什么String类要设计为不可修改的
  1. 方便实现字符串对象池
  2. 线程安全
  3. 更方便缓存hashcode,作为key可以更高效的保存到HashMap

由于每次修改字符串中的内容都要创建新的对象,因此我们可以使用下面这两个类来实现字符串的修改

StringBuilder和StringBuffer
方法说明
StringBuffer append(String str)在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity)扩容
void setCharAt(int index, char ch)将index位置的字符设置为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int fromIndex)从fromIndex位置开始查找str第一次出现的位置
int lastIndexOf(String str)返回最后一次出现str的位置
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找str最后一次出现的位置
StringBuffer insert(int offset, String str)在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuffer deleteCharAt(int index)删除index位置字符
StringBuffer delete(int start, int end)删除[start, end)区间内的字符
StringBuffer replace(int start, int end, String str)将[start, end)位置的字符替换为str
String substring(int start)从start开始一直到末尾的字符以String的方式返回
String substring(int start,int end)将[start, end)范围内的字符以String的方式返回
StringBuffer reverse()反转字符串
反转字符串将所有字符按照String的方式返回

注意:
StringBuilder和String不能相互直接转换,String要想变为StringBuilder,可以调用StringBuilder构造方法,StringBuilder变为String可以调用toString方法

String,StringBuffer,StringBuilder的区别
  1. String不i能被修改,剩下两个可以
  2. StringBuffer采用同步处理,是线程安全的,而StringBuilder未采用,因此尽量使用StringBuffer
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/940180.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号