Java核心

Java String

2018-08-11  本文已影响0人  DjangoW

String在JAVA中是以final修饰的char数组实现的,所以一旦创建了某个string,不可修改。而且String不能被继承(final)。

先来看第一个例子:

String b = "b";
String anotherB="b";
String newB = new String("b");
b == anotherB //true
b == newB //false

其中原委:

b在java加载class的时候会被放入方法区(Method Area)的常量池(Constant Pool)中,之后通过b赋值的变量都被当作constant,直接指向常量池中的内存地址,所以banotherB指向同一个地址。

new String("b")则创建了一个instance,JVM会在执行这条语句的时候(Runtime)在堆(Heap)中为其分配内存,所以和b指向的不是同一个地址。

第二个例子:

String s = "a";
for(int i =0; i < 10; i++)
    s+="a";

编译期间,上段代码会Compiler被优化成:

String s = "a";
for(int i =0; i < 10; i++){
    StringBuilder sb = new StringBuilder(s);
    sb.append("a");
    s=sb.toString();
}

创建了10个StringBuilder实例,所以在loop中不要用string进行操作,不然会在Heap中创建大量短生命周期的instance而加重GC的负担。

第三个例子:

String s = "a" + "b" +"c";

这条语句java创建了多少对象?

一个!因为Compiler会针对这种语句做优化,所以上述语句等价于 String s = "abc";其中abc被当作const处理,加载进jvm的时候放入方法区常量池,s指向该const的地址。所以s == "abc"是true。

另一个例子:

String a = "a";
String ab = a + "b";
System.out.println(ab == "ab"); //false

因为ab赋值中a是变量,编译器不会针对优化。

String VS. StringBuilder VS. StringBuffer

String 为什么设计成immutable的?

  1. literal很常用,设计成final在JVM加载.class类文件的时候会把字符串放到方法区的常量池中,相同的字符串共用同一个常量池地址。
  2. String设计成final的会保证hashCode()也不会改变,从而可以在String中缓存其计算的hash code,不必每次都重新计算。
  3. 如果String是mutable的话,其hashCode()计算的结果也会变,在作为key存取Map的话就会出问题:改变之后的string变量作为key检索不出之前存入的value
上一篇下一篇

猜你喜欢

热点阅读