String 直接继承 Object
含有一个 char[] value, 还有一个 int hash 默认值为 0
new String() 的构造产生的是一个值为 "" 的字符数组
String(char value[], int offset, int count) 当 count=0 且 offset<=value.length 时构造一个值为 "" 的字符串. offset>0 且 offset+count<=value.length 时复制该部分子串. 其余情况都会抛错.
字符数据类型是一个采用 UTF-16 编码表示 Unicode 代码点的代码单元. 大多数的常用 Unicode 字符使用一个代码单元就可以表示, 而辅助字符需要一对代码单元表示. 而 length 返回的是 UTF-16 下的代码单元的数量, 而 codePointCount 返回的是代码点的数量. 对于大部分人工输入的字符, 这两者是相等的, 会出现 length 比 codePointCount 长的通常是某些数学或者机器符号, 需要两个代码单元来表示一个代码点.
对于返回 char[] 的方法, 底层调用的是 System.arraycopy 方法, 这也是高效的数组拷贝函数.
getBytes 方法会调用 StringCoding.encode 返回序列化后的 byte[]
关于 String a == String b 的判断, 是指 a 和 b 指向内存中的同一个对象, 凡是 new String 初始化的对象, 都不会产生 a==b 的情况, 因为他会新开辟一个对象空间, 然后复制 value 的值, 仅当 b=a 初始化时 a==b 成立.
- public static void main(String args[]) {
- String a, b;
- a = "123";
- b = "123";
- System.out.println(a==b);//true
- a = "123";
- b = new String("123");
- System.out.println(a==b);//false
- a = new String("123");
- b = new String("123");
- System.out.println(a==b);//false
- a = "123";
- b = new String(a);
- System.out.println(a==b);//false
- a = new String("123");
- b = a;
- System.out.println(a==b);//true
- }
而 a.equals(b) 先判断 a == b 是否成立, 再判断 b 是否是 String 类, 然后逐个比较 value 数组的值是否相等. equalsIgnoreCase 在此基础上忽略大小写的区别
a.compareTo(b) 比较 a 和 b 第一个不相等字符的差值, 若都相等则比较长度差值. compareToIgnoreCase 多一个忽略大小写的区别. regionMatches(int toffset, String other, int ooffset, int len) 则是比较 a 从 toffset 开始和 other 从 ooffset 开始长度为 len 的部分是否相等.
startsWith(String prefix, int toffset) 字符串从 tooffset 位置开始和 prefix 是否相等. endsWith(String suffix) 字符串结尾和 suffix 等长部分是否相等.
hashCode() 调用时, 若 hash 值为 0 且字符串长度不为 0, 则要计算 hash 值, 方法是 value 数组化为 31 进制
indexOf 是返回第一个出现的指定值的位置, 可以通过 fromIndex 来指定开始查找的位置, 而 indexOfSupplementary 是忽略大小写的该方法. lastIndexOf 则是从尾部开始查找最后一个.
substring 根据指定的位置返回一个新的子字符串, 若指定位置不符合原字符串的长度, 则抛错.
a.concat(String str) 新建一个字符串内容是 a+str 并返回, 不会修改 a 原本的值
- public static void main(String args[]) {
- String a, b;
- a = "123";
- b = "123";
- a.concat(b);
- System.out.println(a);//123
- System.out.println(a.concat(b));//123123
- a = a.concat(b);
- System.out.println(a);//123123
- }
replace(char oldChar, char newChar) 生成一个新的字符串, 将原字符串中的 oldChar 字符全部替换为 newChar, 不会改变原字符串的值. replaceAll(String regex, String replacement) 和前一个方法相比, 参数 regex 是正则表达式, 其余相同.
- public static void main(String args[]) {
- String a;
- a = "12131";
- a.replace("1", "a");
- System.out.println(a);//12131
- a = a.replace("1", "a");
- System.out.println(a);//a2a3a
- }
split(String regex, int limit) 将字符串按照给定的正则表达式分割为字符串组, limit 是分割产生的数组最大数量, 对于多余部分不做分割全部保留在最后一个字符串中.
- public static void main(String args[]) {
- String a;
- a = "1,2,3,4";
- String[] b = a.split(",");
- for(String t : b){
- System.out.print(t + " ");//1 2 3 4
- }
- System.out.println("");
- String[] c = a.split(",", 3);
- for(String t : c){
- System.out.print(t + " ");//1 2 3,4
- }
- }
toCharArray() 复制出一个新的 char[] 而不是直接返回 value
trim() 生成一个新的字符串, 去掉头部的所有空格
public native String intern() 这个方法的作用是在常量池当中寻找是否已经存在该字符串, 若已存在则返回该引用, 若不存在则在常量池新建. 从上面的源码分析中, 我们可以看出 String 的所有操作都是返回一个新的字符串, 对自身是没有修改的, String 被设计为一个不可变的 final 对象, 理由有以下几点:
1. 字符串常量池的需要. 字符串常量池的诞生是为了提升效率和减少内存分配., 因为 String 的不可变性, 常量池很容易被管理和优化.
2. 安全性考虑. 正因为使用字符串的场景如此之多, 所以设计成不可变可以有效的防止字符串被有意或者无意的篡改.(通过反射或者 Unsafe 直接操作内存的手段也可以实现对所谓不可变 String 的修改).
3. 作为 HashMap,HashTable 等 hash 型数据 key 的必要. 因为不可变的设计, jvm 底层很容易在缓存 String 对象的时候缓存其 hashcode, 这样在执行效率上会大大提升.
- public static void main(String args[]) {
- String a, b;
- a = "123";
- b = new String(a).intern();
- System.out.println(a == b);//true
- a = "12" + "3";
- b = "123";
- System.out.println(a == b);//true
- a = "12" + "3";
- b = new String("123");
- System.out.println(a == b);//false
- a = "12" + "3";
- b = new String("123").intern();
- System.out.println(a == b);//true
- a = new String("123");
- b = a.intern();
- System.out.println(a == b);//false
- }
从上面一段代码的运行结果我们可以看到, intern() 会从常量池寻找指定的字符串, 指向同一个常量池对象的时候, a==b 就是成立的. 这里说明一下最后一个 case, 首先常量池存在了 "123", 然后 a 获得的引用是另一个 "123"(因为是 new String 得到的对象), 而 b 得到的是常量池中第一个 "123" 的引用, 所以 a!=b. 对于字符串相加的操作 "12" + "3", 操作过后常量池内会有 3 个字符串,"12" "3" "123"
来源: https://www.cnblogs.com/graywind/p/9400616.html