Java String总结

java

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

回到顶部