【Java 基础】你真的会用 String 吗?

简介: 【Java 基础】你真的会用 String 吗?

“Java不会字符串,开发就得凉一半”


本文将对 String 进行稍微深入全面一点的学习,大佬请回避 ~

总所周知

  String 是Java定义好的一个类。定义在java.lang 包中,而 lang 包是java 的核心包,因此使用的时候不需要导包,而且,是个类,证明String就不属于基本类型,Java的基本类型就那 8 个,String是引用类型

创建String对象的方法

方法名 说明
public String() 创建一个空白字符串对象,不含有任何内容
public String(String original) 根据传入的字符串,创建字符串对象
public String(char[] chs) 根据字符数组的内容,来创建字符串对象
public String(byte[] bys) 根据字节数组的内容,来创建字符串对象
String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc

注意,使用 public String(byte[] bys) 的时候,不是简单的拼接,需要进行ACSII转换,如下

        byte[] bys = {97, 98, 99};
        String s3 = new String(bys);
        System.out.println("s3:" + s3);

输出结果是 abc

String 内存分析

我们看到String类的内部最终是由 char 数组来存储字符串的

现在我们看

String s1 = “abc”;

String s2 = new String("abc")

在内存中的区别

为了节省空间,JVM会在堆区中(JDK 7之前是在方法区中)开辟一个字符串常量池StringTable,用来存放字符串常量,而且是“单例”的,如下

String s3="abc"

String s4="abc"

内存情况如下

所以,我们可以理解为 s1 记录的是 字符串常量 在 字符串常量池中的地址,而 s2 记录的是new String("abc")这个String实例对象在堆中的地址,所以当判断 s1 == s2 时,结果会返回false

因此,如果想比较两个字符串的内容,我们最好使用 equals 方法

StringBuilder & StringBuffer

总所周知,String是不可变的,String不可变不是指


String s="aaa" 后,不能再 s="bbb"


而是说执行上面的代码,不是直接将字符串常量池中的 "aaa" ,改为 "bbb" ,而是会在字符串常量池中新建一个"bbb"常量,然后让引用s指向"bbb"


因为字符串常量的创建会消耗性能,所以如果要对一个String进行频繁的修改,会浪费内存和影响程序效率


在这种场景下,我们可以使用 StringBuilder ,StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的,能极大提高字符串的操作效率

StringBuilder 的构造方法

方法名 说明
public StringBuilder() 创建一个空白可变字符串对象,不含有任何内容
public StringBuilder(String str) 根据字符串str的内容来创建可变字符串对象

StringBuilder 的常用方法

方法名 说明
public StringBuilder append(任意类型) 添加数据并返回对象本身
public StringBuilder reverse() 反转容器中的内容
public int length() 返回长度(字符出现的个数)

public String toString()

实现将 StringBuilder 转换为 String

那么StringBuffer是什么呢?

StringBuffer 和 StringBuilder 几乎相同,只不过 StringBuffer 的方法上都加了同步锁(如下图),因此StringBuffer是线程安全的 ,但是性能较差

字符串拼接的底层原理

        String s1="a";
        String s2=s1+"b";
        String s3="ab";
        System.out.println(s2==s3);

输出 false

        String s1="a";
        String s2="a"+"b";
        String s3="ab";
        System.out.println(s2==s3);

输出 true


为什么呢?


这两个的区别就是在拼接到时候是 纯字符("a"+"b"),还是 存在引用(s1+"b"),纯字符会被优化


本例中创建 String s2="a"+"b" ,在编译的时候,Java会自动优化为 String s2= "ab"


而在JDK8中(JDK7有所不同,但结果一样,不再讲解),创建 String s2=s1+"b" 的过程中,Java会预估一个合适长度(本例为 2)的字符数组,然后分别将 "a" (来自s1) 和 "b" 存入该数组,然后再根据该数组生成 String 对象,相当于是new String,所以此时的s2是指向堆区的,而s3是指向StringTable 的,因此输出 s2==s3 就是fasle

String常用API

最后再总结下String常用API

  • length():返回字符串的长度。
  • charAt(int index):返回指定索引处的字符。
  • substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。
  • equals(Object anObject):比较此字符串与指定对象是否相等。
  • equalsIgnoreCase(String anotherString):比较此字符串与指定字符串是否相等,忽略大小写。
  • indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
  • lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引。
  • startsWith(String prefix):测试此字符串是否以指定的前缀开始。
  • endsWith(String suffix):测试此字符串是否以指定的后缀结束。
  • replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
  • split(String regex):根据正则表达式将此字符串拆分为子字符串,并返回这些子字符串的数组。
  • toCharArray():将此字符串转换为字符数组。
  • toLowerCase():将此字符串转换为小写形式。
  • toUpperCase():将此字符串转换为大写形式。
  • hashCode():计算此字符串的哈希码。
  • constructor():创建一个新的字符串对象,其内容是该参数的字符序列。

目录
相关文章
|
1天前
|
Java UED
Java中String强转int:一种常见的错误和解决方法
在Java中将非数字字符串转换为整数会导致`NumberFormatException`。要解决这个问题,可以使用`try-catch`捕获异常,正则表达式验证数字格式,或利用异常信息提供错误提示。例如,`Integer.parseInt()`会因遇到非数字字符如`"123abc"`而抛出异常,但通过异常处理或正则`\\d+`可确保安全转换。记得在编程时避免直接强转,以防止程序异常中断。
|
1天前
|
Java 数据处理 Apache
探讨Java中判断String类型为空和null的方法
探讨Java中判断String类型为空和null的方法
7 1
|
1天前
|
存储 SQL 关系型数据库
【BUG记录】Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xA6' for column 'name' at row 1
在MySQL中遇到`Incorrect string value`错误通常是因为尝试插入的字符串包含不被数据库字符集支持的字符,如表情符号。错误根源是MySQL默认的utf8不支持4字节的UTF-8字符(如Emoji)。
11 1
|
3天前
|
Java API 索引
java中String类常用API
java中String类常用API
|
15小时前
|
存储 缓存 安全
java源码之String详解
java源码之String详解
|
9天前
|
安全 Java
Java 对象创建与使用:你真的会用吗?
【6月更文挑战第15天】在Java中,对象创建涉及`new`关键字和构造器,用于初始化。使用对象时注重属性和方法的访问,遵循命名规范。关注对象生命周期,避免过度创建,如在循环内,以减少内存消耗和提高性能。还要考虑线程安全,尤其在多线程环境下,确保正确同步以防止数据不一致。通过优化对象的创建与使用,提升代码效率和可靠性。
|
11天前
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
8 0
|
12天前
|
安全 Java 数据安全/隐私保护
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
18 0
|
12天前
|
JSON 安全 Java
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(一)
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(一)
23 0
|
12天前
|
Java
guava Splitter 与java 内置的string的split 方法的区别
guava Splitter 与java 内置的string的split 方法的区别
11 0