Java基础巩固系列 String的内存解析

代码示例:

public class TestString {

    /**
     * String:代表不可变的字符序列。底层使用char[]存放
     * String 是final的
     */
    @Test
    public void test1() {
        String str1 = "JavaEE";
        String str2 = "JavaEE";
        String str3 = new String("JavaEE");
        String str4 = "JavaEE" + "Android";
        String str5 = "Android";
        String str6 = str1 + str5;
        str5 = str5 + "Hadoop";
        String str7 = str6.intern();
        String str8 = "JavaEEAndroid";
        System.out.println(str1 == str2); //true  比较str1和str2的内存地址值
        System.out.println(str1 == str3); //false 比较str1和str3的内存地址值  str3已经new了String地址值已经和str1不一样
        System.out.println(str1.equals(str3));  //true 调用equals,String已经重写了equals的方法所以两个的值是相同的,但地址值依然不同,只不过String重写了equals方法而已

        System.out.println(str4 == str6); //false str6中的str1和str2指向的是两个地址和str4有点区别
        System.out.println(str4.equals(str6)); //true  调用equals,String已经重写了equals的方法所以两个的值是相同的
        System.out.println(str7 == str4); //true  这两种的写法是一样的 str7的intern()方法把两个值直接放到了字符串常量池里
        System.out.println(str4 == str8);  //true  两种的写法是一样的str4相当于是在字符串常量池又造了一个JavaEEAndroid  而str8本身就是JavaEEAndroid 于是两个的地址值一样而字符串常量池里恰好有str4中的值 所以两个的值一模一样
                                            //因此String str1 = "AA" 这种方式是直接在字符串常量池里存储或者查找有没有相同的
        Person p1 = new Person("AA");
        Person p2 = new Person("AA");
        System.out.println(" - -" + (p1.name == p2.name)); //true
    }
}

class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }
}

结果:

true
false
true
false
true
true
true
 - -true

 

内存结构图:

 Java基础巩固系列 String的内存解析