1 String和StringBuilder拼接字符串的区别
总的来说吧,String类的内容是不可变的,StringBuilder的内容是可变的
有好长一段时间都很迷这个String和StringBuilder之间的区别,我想着大家详细介绍一下。
他们之间最主要的区别在于对字符串拼接的处理:
- String在做字符串拼接的时候,不会覆盖掉原来的字符串,原先的字符串还在堆内存里占用着内存,这样一来,拼接的多了,会产生更多的垃圾对象,占去大量内存,现在公司里在拼接字符串这个问题都不采用String,而是采用StringBuilder。
- StringBuilder解决了字符串拼接问题,他所拼接的字符串,会自动覆盖上一级,不会产生多余的垃圾,不会占用太多内存。
- StringBuilder的基本语法
StringBuilder sb = new StringBuilder();
- StringBuilder – append()方法 reverse()反转
//创建对象
StringBuilder sb = new StringBuilder();
//public StringBuilder append(任意类型):添加数据,并返回对象本身
// StringBuilder sb2 = sb.append("hello");
//
// System.out.println("sb:" + sb);
// System.out.println("sb2:" + sb2);
// System.out.println(sb == sb2);
// sb.append("hello");
// sb.append("world");
// sb.append("java");
// sb.append(100);
//链式编程
sb.append("hello").append("world").append("java").append(100);
System.out.println("sb:" + sb);
//public StringBuilder reverse():返回相反的字符序列
sb.reverse();
System.out.println("sb:" + sb);
-
String与StringBuilder之间的转换
-
StringBuilder转换为String
public String toString():通过 toString() 就可以实现把 StringBuilder 转换为 String
-
String转换为StringBuilder
public StringBuilder(String s):通过构造方法就可以实现把 String 转换为 StringBuilder
/*
//StringBuilder 转换为 String
StringBuilder sb = new StringBuilder();
sb.append("hello");
//String s = sb; //这个是错误的做法
//public String toString():通过 toString() 就可以实现把 StringBuilder 转换为 String
String s = sb.toString();
System.out.println(s);
*/
//String 转换为 StringBuilder
String s = "hello";
//StringBuilder sb = s; //这个是错误的做法
//public StringBuilder(String s):通过构造方法就可以实现把 String 转换为 StringBuilder
StringBuilder sb = new StringBuilder(s);
System.out.println(sb);
- StringBuilder常用方法
方法名 说明
public StringBuilder append (任意类型) 添加数据,并返回对象本身public StringBuilder reverse() 返回相反的字符序列
public int length() 返回长度,实际存储值
public String toString() 通过toString()就可以实现把 StringBuilder转换为String
2 String和StringBuilder作为参数的区别
先看下面实例:
public class TestDemo {
@Test
public void test(){
//String str = "hello";
String str = new String("hello");
appendStr(str);
System.out.println(str);
StringBuilder sb = new StringBuilder("hello");
appendSb(sb);
System.out.println(sb);
}
private void appendStr(String s){
s = "world";
}
private void appendSb(StringBuilder s){
s.append("world");
}
}
输出:
hello
helloworld
String作为形参
-
引用str指向new String(“hello”)对象。
-
调用appendStr时,形参s复制了实参str的值,此时形参,实参指向同一个对象,即均指向"hello"这个对象。
-
在appendStr方法内部,将对象“world”的引用被赋给形参s,但并未对实参str产生影响,即实参str依旧指向"hello"这个对象。
-
appendStr方法结束后,形参s在栈内存中释放,对象"world"因不存在被引用,在后续GC(JVM垃圾回收机制)中会被回收。
-
打印str执行的对象内容,依旧是"hello".
StringBuilder作为形参
-
引用str指向new StringBuilder(“hello”)对象。
-
调用appendSb时,形参s复制了实参str的值,此时形参,实参指向同一个对象,即均指向"hello"这个对象。
-
在appendSb方法内部,调用了append的方法,该方法会找到形参所指向的对象,即"hello"这个对象,然后修改了该对象,往后面追加了字符串“world”,即修改了他所指向的对象内容。
-
appendSb方法结束后,形参s在栈内存中释放,对象"helloworld"因还被实参str引用,不会被回收。
-
打印str执行的对象内容,内容已经改变为"helloworld".
区别:
- 在String中appendStr方法内部,给形参赋予了一个新的对象的引用,即形参与实参指向了不同的对象,二者之间没有了关系。
- 而StringBuilder中appendSb方法内部,是操作形参所指向的对象,改变该对象的内容,而形参和实参依旧是指向同一个对象,故实参所指向的对象也就变了
总结:在java中都是值传递,基本类型即是传递原始值,而引用类型则是传递引用所指向的对象的地址。
注意:String虽然属于引用数据类型,但是在传参的时候结果和基本数据类型作为传参传递的结果一致,不会改变