1. String 相关陷阱

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz_cfm/article/details/89674632

1.

public class StringTest {
    public static void main(String[] args) {
        Object object = new Object();
        Object object2 = new Object();
        System.out.println("1: " + (object == object2));

        String str = new String("ym");
        String str2 = new String("ym");
        System.out.println("2: " + (str == str2));

        String str3 = "ym";
        String str4 = "ym";
        System.out.println("3: " + (str3 == str4));

        String str5 = new String("ym");
        String str6 = "ym";
        System.out.println("4: " + (str5 == str6));

        String str7 = "ym";
        String str8 = "y";
        String str9 = "m";
        System.out.println("5: " + (str7 == str8 + str9));
        System.out.println("6: " + (str7 == "y" + "m"));
    }
}

// output
1: false
2: false
3: true
4: false
5: false
6: true

结果分析:

a. 1 和 2 都很容易,因为它们指向的对象不同,所以其引用地址不一样,结果自然就为 false。

b. 3 的结果为 true。这是因为 Java 中有一个 String Pool (常量池)的概念,每次通过 string = "abc"(采用字面值方式赋值) 这种方式在代码中创建 String 对象的时候会首先在 String Pool 中查找有没有这个相同的对象,如果没有就创建一个新的,如果有就不创建新的对象,直接将该对象的地址赋值给相应的引用类型变量。所以上面的 str3 创建了 "ym" 之后,str4 指向的也是同一个字符串对象,导致结果为 true。

c. String s = new String("ym")创建过程:①首先在 String pool 中查找有没有 "ym" 这个字符串对象,如果有,就不用在 String Pool 中再次创建这个对象了,直接在堆(heap)中创建一个 "ym" 字符串对象,然后将堆中这个对象的地址返回给引用变量 s,导致 s 指向堆中创建的这个字符串对象。②如果在 String Pool 中没有,则先在 String Pool 中创建这个对象,然后再在堆中(heap)创建一个 "ym" 对象,最后将堆中的这个对象的地址赋值给引用变量 s,导致 s 指向堆中创建的这个字符串对象。所以在结果 4 中一个指向的是堆中的“ym”对象,一个指向的是栈中(stack)String Pool 中的“ym”对象,它们并不是同一个对象,所以结果返回 false。

d. str7 指向的是 String Pool 中的 "ym" 对象,当"+"两边有一个不为字面值形式的字符串时,它就会在堆里生成一个新的对象,所以 str8 +str9 虽然内容也为 "ym",但是这个 "ym" 对象被创建后是在堆中,所以 str8 + str9 是堆中 “ym”对象的内存地址,所以结果为 false。

e. str7 指向的是 String Pool 中的 "ym" 对象,当"+"两边都为字面值形式的字符串时,它会先在 String Pool 中查找有没有 "ym" 这个对象,如果没有直接在 String Pool 里创建一个新的;如果有就直接返回该对象的地址。所以它们指向的是同一个 String 对象。故为true。

2. 

String 中的 intern() 方法:比如

String str ="ym".intern()

这个方法意思就是,目的是将 "ym" 对象的地址赋值给 str,而创建这个对象时,会首先在 String Pool 中找有没有这个对象,如果有,就直接指向这个对象。如果没有就在 String Pool 中创建这个对象之后再指向它。看个例子:

String str1 = "ym";
String str2 = new String("ym");
String str3 = str2.intern();
System.out.println(str1 == str3);  // true (因为 str1 和 str3 都是指向 String pool 中的 "ym" 对象)
System.out.println(str2 == str3);  // false (因为 str2 指向的是堆中的 "ym" 对象,而 str3 指向的是 String Pool 中的 "ym")

猜你喜欢

转载自blog.csdn.net/yz_cfm/article/details/89674632
今日推荐