String特性
「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战」
不可修改
本来想着说 String不可修改的原因是 String类用 final修饰,导致不可修改;
但是之后看了下 StringBuilder类和 StringBuffer类源码,这些可变字符串类也是用 final关键词修饰的,反应过来不是这个原因;
那 String不可以修改的原因是什么呢?
结论是:String本质上是一个 字符数组常量。
【问题】 为什么把 String设计成不可修改呢?(用 final修饰)
从性能和安全两个角度来可以解释这个问题
安全:String对象作为 Java类库中最常用到的参数,假如不是 final修饰成不可修改,可以被任意篡改,会很危险;
在多线程的情况下,String也是线程安全的。
性能:String用 final修饰下,String的 hash值属性是唯一的,可以放心的对字符串进行缓存,提高性能;
字符串常量池也是基于 String的不可变才可以实现的,一般情况下,创建一个字符串,是从常量池中找,省去了创建新的字符串对象,直接引用常量池的对象即可。
创建字符串的两种方法
1 | ini复制代码String s1 = "hello" |
一道经典的面试题
1 | ini复制代码String a1 = new String("new"); |
【问题】 两种字符串创建方式有什么区别?
使用""
引号创建字符串:
- 会去 方法区-字符串常量池中用 equals()方法找是否有 “”的字符串,
- 如果有,则直接返回该字符串。
- 如果没有,则在 方法区-字符串常量池中创建一个 “”的字符串。
- 如果有,则直接返回该字符串。
使用new
关键字创建字符串:
- 先去 方法区-字符串常量池中用 equals()方法找是否有 “new”的字符串,
- 如果有,继续下一步;
- 如果没有,则在 方法区-字符串常量池中创建一个 “new”的字符串,继续下一步;
- 如果有,继续下一步;
- 再去 堆区创建一个 “new”的字符串对象,返回堆区对象的引用。
扩展知识:通过字符串的 intern()
方法可以获取字符串常量池中字符的地址。
字符串拼接
字符串拼接在项目中很常用到,但是使用不当会造成效率低下;
1 | ini复制代码String s1 = "a"+"b"; |
本质上是创建 StringBuilder对象,使用 append()方法拼接起来,最后用,如果在循环中使用 “+”拼接会创建大量的临时 StringBuilder对象,严重影响性能
1 | ini复制代码StringBuilder s = new StringBuilder(); |
在进行大量字符串拼接时,正确的做法是建议使用 StringBuilder或者 StringBuffer。
字符串常用 API
「删除字符串前后空格」
1 | ini复制代码String s1 = " abc " |
「字母大小写转换」
1 | ini复制代码String s1 = "aB" |
「判断两个字符串是否相等」
1 | ini复制代码String s1 = "s1"; |
「判断字符的开始与结束」
1 | ini复制代码String s1 = "Java"; |
「字符串分割」
1 | ini复制代码String str = "www.baidu.com"; |
「判断是否符合正则规则」
1 | csharp复制代码// 转自菜鸟 |
「字符串长度」
1 | ini复制代码String s1 = "s1"; |
「子串查找」
1 | csharp复制代码String lol = "lol"; |
「字符串截取」
1 | ini复制代码String num = "num"; |
本文转载自: 掘金