String类

String类

String广泛的使用在Java程序开发中,因此有必要深入理解和学习,Java中提供了String类来创建和操作字符串.

1.字符常量池

为了减少在jvm中创建的字符串的数量,虚拟机维护了一个字符串常量池JDK6.0及之前版本,字符串常量池是放在方法区.在JDK7.0版本之后,字符串常量池被移到了堆中了,堆内是可以进行回收的,方法区也是能回收的,但是本身区域内存比较少,如果用的字符串常量太多了,会抛出java.lang.OutOfMemoryError:PermGenspace

  1. 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个Hash表,默认值大小长度是1009;这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。字符串常量由一个一个字符组成,放在了StringTable上。

  2. 在JDK6.0中,StringTable的长度是固定的,长度就是1009,因此如果放入String Pool中的String非常多,就会造成hash冲突,导致链表过长.

  3. 在JDK7.0的后面,StringTable的长度可以通过参数指定,默认为60013:

    -XX:StringTableSize=?????
    

创建字符串的不同方式:

public class StringTest {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        char[] arr = {'h','e','l','l','o'};
        String str3 = new String(arr);
    }
}

内存图如下:
String类_第1张图片

  1. Java中规定双引号""内的都是String对象,且不可修改,储存在常量池内且仅有一份.!
  2. 使用new String(“”)创建的对象会在运行时期创建在堆中,value属性会指向常量池中的字符数组.
  3. 使用"aa"+"bb"直接创建的的变量在编译时期就能确定值,可以直接确定储存在常量池中.
  4. 使用包含string直接量的字符串表达式(如”aa“+s1)创建的对象是运行期才创建的,存储在堆中(不会存储在常量池中;注意:变量在运行时候才知道值为多少编译的时候是不知道的);通过变量/调用方法连接字符串,都只能在运行时候才能确定变量的值和方法的返回值,不存在编译优化操作.
  5. 使用String类带有字符数组的构造方法,不会将该字符串放入常量池中.

什么情况下String对象会被放到常量池中?

  1. "hello"双引号String对象自动放入
  2. 调用String对象的intern()方法:String 对象的 intern 方法会得到字符串对象在常量池中对应的版本的引用(如果常量池中有一个字符串与 String 对象的 equals 结果是 true),如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用;

如下代码解析:一共创建了几个对象.

String s3 = new String("hello")+new String("world");

如何拼接中存在变量,那么Java首先会创建一共StringBuilder类完成整个字符串的拼接.

  1. StringBuilder对象
  2. new String(“hello”)对象
  3. 常量池中的"hello"对象
  4. new String(“world”)对象.
  5. 常量池的"world"对象
  6. new String(value,0,count);(StringBuilder的toString方法调用时产生的对象)

3.String 和 StringBuilder、StringBuffer 的区别?

Java 平台提供了两种类型的字符串:String 和 StringBuffer/StringBuilder,它们可以储存和操作字符串。其中 String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。StringBuilder 是 Java 5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized 修饰,因此它的效率也比 StringBuffer 要高。
String类_第2张图片

你可能感兴趣的:(JavaSE,java)