字符串是Java中使用频率最高的类,但是它却不属于基本类型,而是预定义了String类来表示。从String类的源码可以看到,String是基于char[]实现的,而且Java中的String是不可变字符串,即String初始化之后不可更改。
估计到这就有人问了,字符串不是都可以改的吗?下面两种不都是更改吗?
String a = "123";
a = "1234";
a = a + "F";
这里需要指出的是,字符串在内存中的存放分为两部分,首先内存堆中存放着具体内容,即char[],其次在内存栈中存放着具体内容所在的地址。上面说的不可更改是针对堆中的部分,而我们平时所做的字符串修改是在堆中新建一个char[],然后将栈中的部分修改为新char[]所在的地址,所以与C语言中的字符串更改相比Java中的字符串内容修改效率要稍低一些,而牺牲效率换来的就是不可变的字符串可以共享。
在这里推荐大家在日常的开发工作中使用StringBuffer或StringBuilder来替代“+”,StringBuffer和StringBuilder创建的是可变字符串,在修改结束后调用toString()方式即可使其转变为不可变字符串。StringBuffer和StringBuilder的API相同,区别在于前者是线程安全的,后者线程不安全,而少了线程同步处理换来的就是更高的效率,记得之前测试的好像是StringBuilder的效率是StringBuffer的三倍左右,两者的速度都远高于“+”进行的传统拼接。虽然说三种方式速度都是在毫秒级别处理完,但是在频繁的调用时还是会有不小的差距,所以强烈建议使用StringBuffer和StringBuilder进行字符串的拼接。
再一点就是关于字符串的比较,日常开发中经常会对字符串进行比较,上面说到字符串在内存中的存放方式,所以会出现这么一种情况,堆中的两个char[]内容一样,但是存放的位置不一样,使用==比较时发现两者不相等,所以Java中的字符串比较需要使用equals()方法,此方法比较的是字符串的内容,与存放位置无关。使用==比较会出现这么一个问题:程序中有一个间歇性的BUG,时有时无,原因就是两个字符串对象指向同一个char[]还是指向了两个内容相同的char[]。
更多的关于String的方法可以查看API详细了解。