String类
String是一个对象,是一个引用数据类型,下面介绍一下String类型
-
String和一般引用类型不同,String具有不可变性。例如:Sting s = ”abc“; s=s+“123”; 这里看似字符串s被改变成abc123,其实他是新开辟了一个块空间(补充一个小知识点,String类型定义的字符串都是在常量池中)。在新开辟的内存空间只是把s的指向地址换成了新开辟空间的地址,所以这是String类型拼接的底层过程。所以我们要记住字符串不可变,值的是字符串的内容,一个字符串一旦在内存中创建好了之后就不能被改变
-
扩展:如果非要将一个字符串对象设计为不可变,在JAVA中怎么去设计呢???
答:一个字符串对象其实是通过内部的一个char类型的数组来保存这个字符串内容,这个char类型的数组为final类型的,来保证了数组中变量的值不可变,同时这个数组还是一个private,但是对外没有暴露出get和set方法,只能通过String类的内部使用,所以这个字符串是不可变的。
private final char[] value;
- 为什么JAVA中将String设计为不可变?
答:1.为了实现共享,串池的实现。
2.为了线程安全
String类的常用方法介绍:
这里我不做任注释,只是放方法名。请自行脑补各个方法的使用过程。
-
char c = str.charAt(1);
-
a.compareTo(b)依次比较每个字符的ASCII码,返回int >0 =0 <0
-
String str=“aaa”;
String concat = str.concat(“123”); -
contains(CharSequence s)
-
endsWith(String suffix)判断后缀
-
equals(Object anObject)
-
equalsIgnoreCase(String anotherString) 忽略大小写比较
-
toLowerCase() ,toUpperCase() 大小写转换
-
hashCode() 获取字符串的哈希码
-
indexOf(int ch) 从字符串中获取某个字符第一次出现的位置
-
isEmpty() 注意这里的空不是null
-
replace(char oldChar, char newChar) 替换
-
split(String regex)按照一个特定字符切割,切割完请用对应数组接收
-
substring(int beginIndex ,int overIndex) 字符串的截取
-
trim()
-
String.valueOf(“基本数据类型都可以”) 将基本数据类型转换为字符串
String类型不可变
-
不可变性分析:
1)根据JDK源码进行分析,String类型在实现时,其内部成员变量使用final char[] 来修饰,保证成员变量的引用值只能通过构造方法来修改;
2)当我们在外界修改其内部存储值,看似给我们返回了我们需要的数据,其实在内部新创建了一个String对象把我们修改的值放入其中返回给我们。然而当前的引用指向这一个新的地址。所以有一句话叫:String字符串在改变时,内容没有改变,改变的是引用指向。 -
String不可变性的好处:
1)String对象不可变可以提高效率,因为String对象在StringPool中不可变,所以我们拷贝这个对象的内容时,就不需要去考虑拷贝内容,而是直接把地址拷贝下来,地址的内存占用空间很小,所以效率很高。
2)不可变性对于线程来说是安全的。因为多线程在操作同一个共享数据时会修改它的值,此时如果对象时可变的,那就会导致线程不安全。
3)可以实现共享。同一个字符串可以被多个线程共享,由于它的不可变性,所以不需要考虑线程安全问题。