JVM 虚拟机 之 内存分配代码图解 (字符串 )

转自:http://www.verejava.com/?id=17433712313614
1. 字符串直接赋值

package com.jvm4;

public class Test {

    public static void main(String[] args) {
        String s1="天道酬勤";
        String s2="天道酬勤";

        System.out.println("s1==s2 : "+(s1==s2));
        System.out.println("s1.equals(s2) : "+s1.equals(s2));
    }
}


运行结果:


s1==s2 : true

s1.equals(s2) : true


图解:


JVM 虚拟机 之 内存分配代码图解 (字符串 )_第1张图片


s1 和 s2 同时指向 字符串常量池 同一个对象

s1==s2 比较对象引用 所以相等 返回 true

s1.equals(s2) 比较内容 都是 “天道酬勤” 返回 true

创建的对象为 1 个


2. 字符串实例化


package com.jvm4;

public class Test2 {

    public static void main(String[] args) {
        String s3=new String("天道酬勤");
        String s4=new String("天道酬勤");

        System.out.println("s3==s4 : "+(s3==s4));
        System.out.println("s3.equals(s4) : "+s3.equals(s4));
    }
}


运行结果:


s3==s4 : false

s3.equals(s4) : true


图解:


JVM 虚拟机 之 内存分配代码图解 (字符串 )_第2张图片


s3 和 s4 指向 堆 中不同的 “天道酬勤” 对象

s3==s4 比较对象引用 所以不相等 返回 false

s3.equals(s4) 比较内容 都是 “天道酬勤” 返回 true

创建的对象为 3 个 : 2 个堆中的对象  1 个字符串常量池中的对象


3. 字符串实例化 和 赋值


package com.jvm4;

public class Test3 {

    public static void main(String[] args) {
        String s1="天道酬勤";
        String s3=new String("天道酬勤");

        System.out.println("s1==s3 : "+(s1==s3));
        System.out.println("s1.equals(s3) : "+s1.equals(s3));
    }
}


运行结果:


s1==s3 : false

s1.equals(s3) : true


图解:


JVM 虚拟机 之 内存分配代码图解 (字符串 )_第3张图片


s1 指向 字符串常量池的 “天道酬勤” 对象 , s3 指向 堆中的 “天道酬勤” 对象

s1==s3 比较对象引用 所以不相等 返回 false

s1.equals(s3) 比较内容 都是 “天道酬勤” 返回 true

创建的对象为 2 个 : 1 个堆中的对象  1 个字符串常量池中的对象


4. 字符串String ,StringBuilder,StringBuffer


package com.jvm4;

public class Test4 {

    public static void main(String[] args) {
        String s="天"+"道"+"酬"+"勤";

        StringBuilder sber=new StringBuilder();
        sber.append("天").append("道").append("酬").append("勤");

        StringBuffer sbfer=new StringBuffer();
        sbfer.append("天").append("道").append("酬").append("勤");

        System.out.println("s : "+s);
        System.out.println("StringBuilder : "+sber.toString());
        System.out.println("StringBuffer : "+sbfer.toString());
    }
}


运行结果:


s : 天道酬勤

StringBuilder : 天道酬勤

StringBuffer : 天道酬勤


图解:


JVM 虚拟机 之 内存分配代码图解 (字符串 )_第4张图片


String 每次 + 都得创建对象 一共创建了 7 个

而StringBuilder 和 StringBuffer append 不用创建新的对象

所以在大量字符串拼接的时候用 StringBuilder 和 StringBuffer  效率高占用内存少


StringBuilder append 源码


public StringBuilder append(String str){
    super.append(str);
    return this.
}



StringBuffer append 源码


public synchronized StringBuffer append(String str){
    super.append(str);
    return this.
}



StringBuilder 线程不安全 , StringBuffer 加了 synchronized 线程安全

所以在多线程并发的时候用 StringBuffer , 单线程用 StringBuilder 效率高

你可能感兴趣的:(JVM)