为什么String类是不可变类
先来看一下内部结构:
private final char value[];
首先需要补充一个容易混淆的知识点:当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。例如某个指向数组的final引用,它必须从此至终指向初始化时指向的数组,但是这个数组的内容完全可以改变。
我们来看一下String类的两个主要成员变量,其中value指向的是一个字符串数组,字符串中的字符就是用这个value变量存储起来的,并且用final修饰,也就是说value一旦赋予初始值之后,value指向的地址就不能再改变了。虽然value指向的数组是可以改变的,但是String也没有提供相应的方法让我们去修改value指向的数组的元素。然而在StringBuilder中是提供了响应的方法让我们去修改value指向的数组的元素,这也是StringBuilder的字符串序列可变的原因。
如何判断String 是否为空
首先了解两种场景
- 引用为空,没有地址
String str1 = null;
- 有地址,但值为空
String str2 = "";
由于引用数据类型中 == 比较的是地址值,equals比较的是内容。所以如果string对象是null,不用==来判断会抛出异常。
综合来说判断String是否为空通常有以下几种方法:
- 这是效率比较高的一种方法
if(s == null || s.length() == 0);
- 使用Java SE6 加入的方法,但是考虑到兼容性最好使用第一种
if(s == null || s.isEmpty());
- 很直观的方法,效率和第一种差不多
if (s == null || s == "");
- 很直观,但是不推荐,效率比较低
if(s == null || s.equals(""));
String常用 API
方法名 | 方法说明 |
---|---|
length() | 获取字符串的长度 |
hashCode() | 返回字符串的哈希值 |
tirm() | 返回字符串两边消除空格后的字符串 |
isEmpty() | 判断字符串是否为空 |
equals(String s) | 判断两个字符串内容是否相同 |
equalsIgnoreCase(String s) | 不区分大小写判断两个字符串内容是否相同 |
charAt(int index) | 返回下标所在的cha值(字符) |
indexOf(String s) | 返回字串第一次出现的位置,没出现则返回-1 |
lastIndexOf(String s) | 返回字串最后一次出现的位置,没出现返回-1 |
starstWith(String prefix) | 判断字符串是否以prefix为前缀开头 |
toLowerCase() | 返回字符串的小写形式 |
toUpperCase() | 返回字符串的大写形式 |
compareTo | 将字符串与另一个对象进行比较 |
substring(int startindex,int endindex) | 返回从startindex开始到endindex结束的字串 |
contains(String s) | 判断是否包含字串s |
concat(String s) | 字符串拼接,相当于+ |
replaceAll(String oldSrt,String newSrt) | 替换原有字符串中的字串为目标字串 |
split(String split) | 以指定字符串分割后返回字符串数组 |
getBytes() | 返回字符串的字节数组 |
tocharArray() | 将此字符串转换为一个新的字符数组 |