jdk8以前:
private final char value[];
jdk9以后:
private final byte[] value;
,为节省内存空间而优化
不管什么操作改变的永远是引用地址,不是字符串!
“=”声明的字符串保存在字符串常量池中,new String()创建的字符串保存在堆中
保存在字符串常量池中共。
return new String(...)
创建了一个新的String对象。 return new String(...)
创建了一个新的String对象。保存在堆空间中,因为是对象。
虽然我们只new了一个对象,但底层是创建了两个对象。
字符串还是保存在字符串常量池的,两个对象都通过value属性指向了字符串常量的位置。
注意: 内存中两个对象保存的相同字符串的地址是相同的,但是两个对象对应的引用地址是不行同的。
由图可见,有变量参与的和字符串常量的拼接,底层的操作是不同的(比较值不一样)。
对于字面量字符串,Java编译后会自动将其拼接。对于有变量参与的则不同。
所以对于字面量声明的字符串,不会创建对象,比较的是值,所以为true。
有变量参与的,底层会通过new重新创建对象,所以引用保存了不同的内存地址。
所以 “==”比较的是内存地址,输出false。
底层通过StringBuilder.append()方法向StringBuilder添加元素,最后通过StringBuilder.toString()方法将StringBuilder转换成String(new String())。
因为返回 的是地址,所以“==”结果为true
注意:字符串是引用数据类型,引用保存的是内存地址
示例:
//字面量定义方式:字符串常量对象
String str = "hello";
//构造器定义方式:无参构造
String str1 = new String();
//构造器定义方式:创建"hello"字符串常量的副本
String str2 = new String("hello");
//构造器定义方式:通过字符数组构造
char chars[] = {'a', 'b', 'c','d','e'};
String str3 = new String(chars);
String str4 = new String(chars,0,3);
//构造器定义方式:通过字节数组构造
byte bytes[] = {97, 98, 99 };
String str5 = new String(bytes);
String str6 = new String(bytes,"GBK");
常用方法
(1)boolean isEmpty():字符串是否为空 (2)int length():返回字符串的长度 (3)String concat(xx):拼接 (4)boolean equals(Object obj):比较字符串是否相等,区分大小写 (5)boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写 (6)int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小 (7)int compareToIgnoreCase(String other):比较字符串大小,不区分大小写 (8)String toLowerCase():将字符串中大写字母转为小写 (9)String toUpperCase():将字符串中小写字母转为大写 (10)String trim():去掉字符串前后空白符 (11)public String intern():结果在常量池中共享
(13)boolean contains(xx):是否包含xx (13)int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1 (14)int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 (15)int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1 (16)int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
(17)boolean contains(xx):是否包含xx (18)int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1 (19)int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 (20)int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1 (21)int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
(22)char charAt(index):返回[index]位置的字符 (23)char[] toCharArray(): 将此字符串转换为一个新的字符数组返回 (24)static String valueOf(char[] data) :返回指定数组中表示该字符序列的 String (25)static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String (26)static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String (27)static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String
(28)boolean startsWith(xx):测试此字符串是否以指定的前缀开始 (29)boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始 (30)boolean endsWith(xx):测试此字符串是否以指定的后缀结束
(31)String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 不支持正则。 (32)String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 (33)String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 (34)String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。