String 类方法(不可以被继承,不可变)
- 获取方法
- 长度
- 特定字符位置
- 最后一个字符的位置
- 判断方法
- 是否以指定字符结束
- 是否长度为 0 “” 或者 null
- 搜索(是否包含)
- 是否相等
- 忽略大小写
转换方法 - 将字符数组转换为字符串
- 将字符串转换为字符数组
- 替换
- 切割
- 转大/小写
String,StringBuffer,StringBuilder 的区别
-
可变不可变
String, 字符串常量 修改相当于生成新的字符串对象
StringBuffer, 变量 每次改 都是对 对象本身进行 -
线程是否安全
String, 安全
StringBuffer, 安全 (对调用方法加入同步锁) 效率慢 用于多线程操作字符串缓冲区
StringBuilder 不安全 , 用于单线程下操作字符串缓冲区 -
共同点
String,
StringBuffer,StringBuilder 父类都是AbstractStringBuilder
补充:
- 需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:
StringBuffer s = “abc”; //赋值类型不匹配
StringBuffer s = (StringBuffer)”abc”; //不存在继承关系,无法进行强转
StringBuffer对象和String对象之间的互转的代码如下:
String s = “abc”
StringBuffer sb1 = new StringBuffer(“123”)
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer
String s1 = sb1.toString(); //StringBuffer转换为String
-
对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象
-
StringBuffer方法
(1) append()
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。
(2) delete (1,4)
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。
(3)insert()
.insert(4,false)
该示例代码的作用是在对象的索引值4的位置插入false值,形成新的字符串
(4)reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串
(5) void setCharAt(int index, char ch)方法
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
setCharAt(1,’D’) 则对象的值将变成”aDc”。
(6)trimToSize方法
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
- String str1 = “hello world”;和String str3 = “hello world”; 都在编译期间生成了 字面常量和符号引用,运行期间字面常量"hello world"被存储在运行时常量池(当然只保存了一份)。通过这种方式来将String对象跟引用绑定的话,JVM执行引擎会先在运行时常量池查找是否存在相同的字面常量,如果存在,则直接将引用指向已经存在的字面常量;否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。
通过new关键字来生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的。因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。
string+="hello"的操作事实上会自动被JVM优化成:
StringBuilder str = new StringBuilder(string);
str.append(“hello”);
str.toString();
-
StringBuilder和StringBuffer类拥有的成员属性以及成员方法基本相同,区别是StringBuffer类的成员方法前面多了一个关键字:synchronized,这个关键字是在多线程访问时起到安全保护作用的,也就是说StringBuffer是线程安全的。
-
当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;
当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。 -
String a = “hello2”; final String b = “hello”; String c = b + 2; System.out.println((a == c));
输出结果为:true。对于被final修饰的变量,会在class文件常量池中保存一个副本,也就是说不会通过连接而进行访问,对final变量的访问在编译期间都会直接被替代为真实的值。那么String c = b + 2;在编译期间就会被优化成:String c = “hello” + 2;
-
String str = new String(“abc”)创建了多少个对象?
首先必须弄清楚创建对象的含义,创建是什么时候创建的?这段代码在运行期间会创建2个对象么?
- 广为流传的答案: 两个
(一个是“abc”驻留(intern)在一个全局共享的字符串常量池中的实例,
一个是指向“abc”的引用对象s,通过new String(String)创建并初始化的、内容与"abc"相同的实例) - 这个问题自身就没有合理的答案