Java String总结
1.String字符串常量池
JVM为了提高性能和减少内存开销,内部维护了一个字符串常量池,每当创建字符串常量时,JVM首先检查字符串常量池,如果常量池中已经存在,则返回池中的字符串对象引用,否则创建该字符串对象并放入池中。
因此下述结果返回true。
1 String a = "abc";2 String b = "abc";
3 System.out.print(a == b); //true
但与创建字符串常量方式不同的是,当使用new String(String str)方式等创建字符串对象时,不管字符串常量池中是否有与此相同内容的字符串,都会在堆内存中创建新的字符串对象。
因此,下面代码片段有如下结果。
1 String a = "Hello";2 String b = new String("Hello");
3 System.out.println(a == b); //false
4 System.out.println(a.equals(b)); //true
即使字符串内容相同,字符串常量池中的字符串与通过new String(..)等方式创建的字符串对象之间没有直接的关系,但是,可以通过字符串的intern()方法找到此种关联。intern()方法返回字符串对象在字符串常量池中的对象引用,若字符串常量池中尚未有此字符串,则创建一新的字符串常量放置于池中。
于是,很据如上理解,很自然的,可以得到如下结果。
1 String a = "Hello";2 System.out.println(a == a.intern()); //true
3
4 String b = new String("corn");
5 String c = b.intern();
6
7 System.out.println(b == c); //false
8
9 String d = "corn";
10
11 System.out.println(c == d); //true
2.String/StringBuilder/StringBuffer区别
String是不可变字符串对象,StringBuilder和StringBuffer是可变字符串对象(其内部的字符数组长度可变),StringBuffer线程安全,StringBuilder非线程安全。
3.既然String是不可变字符串对象,如何才能改变让其可变?
既然String对象中没有对外提供可用的public setters等方法,因此只能通过Java中的反射机制实现。因此,前文中说到的String是不可变字符串对象只是针对“正常情况下”。而非必然。
public static void stringReflection() throws Exception {2
3 String s = "Hello World";
4
5 System.out.println("s = " + s); //Hello World
6
7 //获取String类中的value字段
8 Field valueField = String.class.getDeclaredField("value");
9
10 //改变value属性的访问权限
11 valueField.setAccessible(true);
12
13 char[] value = (char[]) valueField.get(s);
14
15 //改变value所引用的数组中的第5个字符
16 value[5] = '_';
17
18 System.out.println("s = " + s); //Hello_World
19 }
由此可见Java中反射的强大之处。
以上是 Java String总结 的全部内容, 来源链接: utcz.com/z/394365.html