string对象是不可变的,字符串一旦创建,内容不能再改变。底层用char[]存放,故可以使用字符串直接量或字符数组创建一个字符串对象(其中string类中有13个构造方法),下面的语句使用字符串直接量
java将字符串直接量看着string对象,所以,下面的语句是合法的:
还可以用字符数组创建一个字符串
注意:string变量存储的是对string对象的引用,string对象里存储的才是字符串的值。严格地讲,术语string变量、string对象和字符串值是不同的。但在大多数情况下,它们之间的区别是可以忽略的。为简单起见,术语字符串将经常被用于指string变量、string对象和字符串的值。
不可变字符串与限定字符串
string对象是不可变的,它的内容是不能改变的。下列代码会改变你字符串的内容吗?
答案是不能.第一条语句创建了内容为“java”的string对象,并将其引用赋值给s。第二条语句创建了一个内容为“html”的新string对象,并将其引用赋值给s。赋值后第一个string对象仍然存在,但是不能再访问它,因为变量s现在指向了新的对象。
因为字符串是不可改变的,但同时又会频繁的使用,所以java虚拟机为了提高效率并节约内存,对具有相同字符序列的字符串直接量使用同一个实例。这样的实例称为限定的(interned)字符串。例如,下面的语句:
从字节码和常量池的角度来分析下刚才这些代码的底层原理
string的常用操作
字符串的替换和分割
一旦创建了字符串,它的内容就不能改变。但是,方法replace、replaceall和replacefirst会返回一个源自原始字符串的新字符串(并未改变原始字符串)。replace方法有几个重载方法。split方法可以从一个指定分隔符的字符串中提取标识。
string token = "赵老师是一个好老师,你喜欢赵老师吗?";
//将所有的赵老师替换为miss cang
string info = token.replace("赵老师", "miss cang");
system.out.println(info);
//替换第一个找到的赵老师
system.out.println(token.replacefirst("赵老师", "miss cang"));
//替换全部,支持模式匹配(正则表达式)
system.out.println(token.replaceall("赵老师", "miss cang"));
依照模式匹配、替换和分割
详情请参考正则表达式
字符串与数组之间的转换
字符串不是数组,但是字符串可以转换成数组,反之亦然。
将字符和数值转换成字符串
回顾下,可以使用double.parsedouble(str)或者integer.parseint(str)将一个字符串转为一个double或者int值,也可以使用字符串的连接操作符将字符或者数值转换为字符串。另外一种将数字转为字符串的方法是使用重载的静态valueof方法。
格式化字符串
string.format(format,item1,item2,...,itemn)
stringbuffer和stringbuilder
stringbuffer和stringbuilder类似于string类,区别在于string类是不可改变的。一般来说,只要使用字符串的 地方,都可以使用stringbuffer/stringbuilder类.stringbuffer和stringbuilder比string更加灵活。可以给一个stringbuffer和stringbuilder中添加、插入或追加新的内容,但是string对象一旦创建,它的值就固定了。
除了stringbuffer中修改缓冲区的方法是同步的(只有一个任务被允许执行),stringbuffer与stringbuilder类是很相似的。如果是多任务并发访问,就使用stringbuffer,可以防止stringbuffer崩溃。而如果是单任务访问,使用stringbuilder会更有效。stringbuffer和stringbuilder中的构造方法和其它方法机会是完全一样的
示例:判断回文字符串时忽略既非字母又非数字的字符