【JAVA】String类 详解

String 类

Java中的String类是一个非常重要的类,用于表示不可变的字符序列。String类在java.lang包中定义,并且在Java程序中广泛使用。下面是String类的一些关键特点和功能:

1. 不可变性(Immutability)

  • String对象一旦创建,其内容不可更改。例如,调用字符串的任何修改方法(如replace、toUpperCase等)都会返回一个新的String对象,而不会改变原来的字符串。
  • 不可变性使得String在多线程环境中是安全的,因为不需要同步机制来防止并发修改。

2. 存储结构

  • String类内部使用一个字符数组(char[])来存储字符串的字符序列。在Java 9之前,String类使用的是UTF-16编码的字符数组(每个字符占用2字节),从Java 9开始,为了节省内存,如果字符串内容都在Latin-1字符集内,String类使用字节数组(byte[])存储字符串,并结合编码标识来区分。

3. 常量池(String Pool)

  • Java中有一个特殊的内存区域称为“字符串常量池”,用于存储字符串字面值。在编译期间,所有的字符串字面值都会被放入这个池中,如果创建一个新的字符串时,池中已经存在相同内容的字符串对象,Java不会创建新的对象,而是直接返回池中的引用。这种机制可以减少内存的浪费。
  • 可以通过intern()方法将一个String对象手动放入常量池中。

4. 创建方式

  • 直接赋值:String str = “Hello”;
  • 通过构造函数:String str = new String(“Hello”); 这种方式虽然可以创建一个新的字符串对象,但不推荐使用,因为它不利于性能优化。

5. 常用方法

  • length():返回字符串的长度。
  • charAt(int index):返回指定索引处的字符。
  • substring(int beginIndex, int endIndex):返回子字符串。
  • equals(Object obj):比较两个字符串的内容是否相等。
  • compareTo(String anotherString):按字典顺序比较两个字符串。
  • toUpperCase():将字符串转换为大写。
  • toLowerCase():将字符串转换为小写。
  • trim():去除字符串两端的空白字符。
  • replace(char oldChar, char newChar):替换字符串中的字符。
  • split(String regex):根据正则表达式拆分字符串。
  • contains(CharSequence s):判断字符串是否包含指定的字符序列。
  • indexOf(String str):返回指定字符或子字符串在此字符串中首次出现的位置。
  • lastIndexOf(String str):返回指定字符或子字符串在此字符串中最后一次出现的位置。

6. 字符串拼接

  • 使用+操作符:String result = “Hello” + " World";。在编译时,Java会将这些字符串拼接优化为一个StringBuilder的append操作。
  • StringBuilder或StringBuffer:如果需要在循环中多次拼接字符串,建议使用StringBuilder(线程不安全)或StringBuffer(线程安全)以提高性能。

7. 正则表达式

  • matches(String regex):判断字符串是否匹配指定的正则表达式。
  • replaceAll(String regex, String replacement):使用正则表达式匹配并替换字符串中的内容。
  • split(String regex):根据正则表达式拆分字符串。

8. 性能注意事项

  • 由于String的不可变性,每次修改都会产生一个新的对象,因此在需要频繁修改字符串的场景中,应使用StringBuilder或StringBuffer来避免性能损耗。
    String类是Java中非常基础和重要的类,了解其内部工作机制和使用方法对编写高效的Java程序至关重要。

9. 面试题

面试题 1: 解释Java中String类的不可变性以及它的好处是什么?

答案要点:

  • String类是不可变的,意味着一旦创建,字符串的内容就不能被改变。如果尝试修改字符串,实际上会创建一个新的String对象。
  • 好处包括:
    • 线程安全:由于不可变,String对象可以在多线程环境中安全地共享,而无需同步机制。
    • 字符串常量池优化:Java中的字符串常量池能够缓存不可变的String对象,从而节省内存并提高性能。
    • 安全性:不可变性防止了对象的内容被意外或恶意修改(例如作为方法参数传递时)。

面试题 2: String、StringBuilder和StringBuffer之间有什么区别?什么时候应该使用StringBuilder而不是String?

答案要点:

  • String:
    • 不可变的字符序列。
    • 每次修改都会创建一个新的对象。
    • 适用于少量字符串拼接或不需要频繁修改的情况。
  • StringBuilder:
    • 可变的字符序列,非线程安全。
    • 提供了可修改字符串的能力,适用于在单线程环境中频繁修改字符串的情况。
    • 比String在性能上有明显的优势,特别是在循环中进行多次拼接时。
  • StringBuffer:
    • 可变的字符序列,线程安全。
    • 提供了线程安全的字符串修改能力,适用于在多线程环境中频繁修改字符串的情况。
    • 由于同步开销,一般比StringBuilder稍慢。
  • 使用场景:
    • 当需要频繁修改字符串内容时,应该使用StringBuilder以提高性能。
    • 如果需要在多线程环境中操作字符串,则选择StringBuffer。

面试题 3 如何在Java中手动将一个String对象放入字符串常量池中?intern()方法的工作原理是什么?

答案要点:

  • 在Java中,可以使用intern()方法将一个String对象手动放入字符串常量池中。
  • intern()方法的工作原理:
    • 如果常量池中已经存在一个与调用intern()方法的字符串内容相同的对象,则返回池中该字符串的引用。
    • 如果常量池中不存在这个字符串,则将该字符串对象添加到池中,并返回该对象的引用。

示例代码:

String str1 = new String("Hello");
String str2 = str1.intern(); // 将str1的内容放入常量池中,并返回常量池中的引用

String str3 = "Hello"; // 已经在常量池中
System.out.println(str2 == str3); // true,str2和str3都指向常量池中的同一个对象

这个方法对于优化内存使用特别有用,因为它允许多个String对象共享相同的内存空间。

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值