//当string使用字面量赋值时,字符串保存在字符串常量池中(常量池中不会有重复的字符串)
//当string使用new赋值时,和平常的对象一样,字符串保存在堆中
//所以str1 和 str2 保存的地址值相同,而 str1 和 str3 保存的地址值不同
public class StringTest {
public static void main(String[] args) {
String str1 = "test";
String str2 = "test";
String str3 = new String("test");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
//常量拼接是在常量池中操作,只要有变量,结果就是在堆中
//所以s5和s3的地址值是相同的(常量池中不能存在两个一样的变量)
//s4,s6有变量参与,相当于new,结果保存在堆中
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = s1 + s2;
String s5 = "hello" + "world";
String s6 = s1 + "world";
final String s9 = "hello"; //常量
String s8 = s9 + "world";
System.out.println(s3 == s4); //false
System.out.println(s3 == s5); //true
System.out.println(s4 == s6 ); //false
System.out.println(s8 == s3); //true
//jdk1.6中,使用intern()后,string对象只会引用或创建在字符串常量池中的对象
//jdk1.7后,使用intern()后,string对象需要注意引用的是字符串常量池还是堆中的对象(在常量池的话就是引用的常量池中的对象,堆中的话就是引用堆中的)
//概括:intern()方法设计的初衷就是为了重用string对象,来节省内存消耗
String s7 = s4.intern();//返回值为常量池中已经存在的值
System.out.println(s7 == s3); //true
String s = new String("1") + new String("2");
System.out.println(s.intern() == s);
}
}
//由于字符串的不可变性,每次重新赋值的时候,如果常量池中没有,都会
//在常量池中创建一个,此时局部变量的str指向了“test2”,而main中的str还是指向“test”
public class StringTest2 {
public static void main(String[] args) {
String str = "test";
char[] s ={'t','e','s','t'};
exchange(str,s);
System.out.println(str);
System.out.println(s);
}
public static void exchange(String str,char[] s) {
str = "test2";
System.out.println(str);
s[0] = 'b';
}
}
结果
test2
test
best
因为当main中的str传入到exchange中时,exchange中的str和main中的str是两个不同的变量,但是指向的是同一个地址,而当exchange中给str重新赋值时,由于在常量池中没有找到“test2”,所以会在常量池中创建一个“test2”,并让exchange中的str指向它。
包装类和string之间的转换
public class StringTest3 {
public static void main(String[] args) {
//string类型转包装类、基本类型
String s = "123";
int i = Integer.parseInt(s);
System.out.println(i);
//基本类型转string
String s1 = String.valueOf(i);
System.out.println(s1);
//string转换为char[]
char[] chars = s1.toCharArray();
for (char o : chars) {
System.out.println(o);
}
//string转换为byte[]
String s2 = "abc";
byte[] bytes = s2.getBytes();//使用默认的字符集进行转换
// try {
// byte[] bytes1 = s2.getBytes("utf-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
System.out.println(Arrays.toString(bytes));
// for (byte aByte : bytes) {
//// System.out.println(aByte);
//// }
//解码
System.out.println(new String(bytes));
}
}
StringBuffer和StringBuilder
StringBuffer中的方法大多是同步方法,线程安全,但速度较慢
StringBuilder线程不安全,但是速度较快
与String相比,这两个是可变的