Java中字符串的使用是最常见的,本文总结字符串使用中需要注意的地方。
不可变
从String的源码可以看到这是一个final类,其主要的字段也是final的,而且每个修改字符串的方法也是重新创建一个值返回的,这也是值得推荐的,毕竟对于方法而言,参数更应该是提供信息,而不应该去修改参数。
1 | public final class String implements java.io.Serializable, Comparable<String>, CharSequence { |
可以看到其实内部就是一个字符数组来存储的。对于源码的分析就不在这里展开了。
字符串的创建
字符串都是存储在Java虚拟机的字符串常量池中的。一般可分为两种创建方式:
String s = "abc"
直接创建:会先判断在常量池中是否存在abc这个字符串,有则直接返回引用,没有则创建再返回引用。
String s = new String("abc")
通过对象创建:同样也会先判断在常量池中是否存在abc这个字符串,有则将abc赋值给new String这个对象,然后将对象的引用返回给s,如果在常量池中没有,则先创建,再重复存在的情况。其中会创建三个东西,s是引用在java虚拟机栈中,String对象在Java堆上,abc会在常量池中。
注意常量池已经在jdk1.7以后从Java虚拟机的方法区移到了Java堆内存中
重载“+”与StringBuilder
在字符串的使用中,发现使用+号连接是非常方便的,这是系统为我们重载的,在c++中我们也是可以重载操作符的,但是java不允许。通过将class文件转为字节码可以看到(使用命令javap -c c class文件路径),重载+的实质就是使用StringBuilder来拼接这些+号连接的字符串。
所以需要注意在for 循环中不要直接使用+号去拼接字符串,那样就会导致重复创建StringBuilder对象浪费内存资源,应该直接在for 循环外创建一个StringBuilder然后在循环中手动append。但是也需要注意在append的时候,若是有多个字符串,参数中也不要使用+号去连接,而应该多次调用append,不然也会导致重复创建StringBuilder对象。正确的使用例如:
1 | StringBuilder stringBuilder = new StringBuilder(); |
无意识的递归
每个类都有一个toString的方法,默认的toString方法会打印出这个类的名字+@符号+内存地址的十六进制值,这一点从源码可以看到。
1 | public String toString() { |
而在继承自Object的类,重写toString方法之后想要打印内存地址,就得调用Object的toString方法,而不要使用this这个对象。虽然听上去很低级,但是确实也很低级。
String常用的方法
方法名 | 含义 |
---|---|
length() | 字符串的长度 |
charAt(int index) | index位置上的字符串是什么 |
toCharArray() | 复制内容到一个char数组并返回 |
contains(CharSequence s) | 是否包含某个字符串 |
equals(Object anObject) | 比较两个字符串是否相同 |
stratsWith(String prefix) | 字符串是否以某个字符串开头 |
endsWith(String suffix) | 字符串是否以某个字符串结尾 |
indexOf(int ch) | 某个字符在字符串中的位置,从头开始查找,如果不存在则返回-1 |
lastIndexOf(int ch) | 某个字符在字符串中的位置,从头最后开始查找,如果不存在则返回-1 |
subString(int beginIndex, int endIndex) | 在原字符串中从开始位置到结束位置截取得到一个字符串返回 |
replace(char oldChar, char newChar) | 在字符串中将所有旧的字符串换成新的字符串 |
split(String regex) | 将字符串按照某个字符串或者正则表达式拆分成字符串数组 |
matches(String regex) | 判断该字符串与某个字符串或者正则表达式是否匹配 |
String、StringBuilder与StringBuffer三者之间的区别
String是只读字符串,所以字符串内容是不能被修改的。StringBuffer和StringBuilder中字符串是可修改的,用法也相同,只是前者是多线程时使用,有锁的机制,后者是jdk1.5以后加入的,适用于单线程,效率会比StringBuffer高一点。
总结
对于字符串的使用确实非常重要,对于正则表达式便是字符串的使用中最厉害的。对于正则表达式将会单独去学习总结。