一、String建立的對象有兩種,一種在緩沖池中建立,一種在堆中建立,以下列舉說明:
1.String s=new String("abc");
建立對象時,首先括号中的abc會先檢視緩沖池中是否存在abc,如果存在不再建立,不存在則在緩沖池中建立abc,然後,new會在堆中建立一個對象abc(無論堆中是否有abc,每new一次都會建立一個新的),這裡的s指向的是堆裡的abc,詞條語句建立兩個abc對象;
2.String s1="abc";
建立對象時,abc會直接到緩沖池中檢視是否存在abc,如果存在不再建立,不存在則在緩沖池中建立abc,s1指向緩沖池中的abc;
二、案例
案例1.
①String s = new String("abc");
②String s1 = "abc";
③String s2 = new String("abc");
④System.out.println(s == s1);
⑤System.out.println(s == s2);
⑥System.out.println(s1 == s2);
解析:①括号中abc檢視在緩沖池中是否存在abc,不存在,則在緩沖池中建立一個,緊接着new會在堆中建立新對象abc,并且讓s指向堆中abc;
②abc檢視緩沖池中是否存在abc,存在,不再建立,s1直接指向緩沖池中的abc;
③括号中abc檢視在緩沖池中是否存在abc,存在,不再建立,緊接着new會在堆中建立abc,并且讓s2指向堆中建立新對象abc,每new一次建立一個新的,是以和s指向的不是一個;
④s指向堆中abc,s1指向緩沖池中abc,是以false;
⑤同理④,是以false;
⑥s1和s2都是指向堆中abc,但每new一次會建立一個新的abc,是以指向的不是同一個,故false;
案例2.
①String s = new String("abc");
②String s1 = "abc";
③String s2 = new String("abc");
④System.out.println(s == s1.intern());
⑤System.out.println(s == s2.intern());
⑥System.out.println(s1 == s2.intern());
解析:
intern()說明:傳回對應這個字元串内容的那個緩沖池裡的對象,如s1.intern()的執行流程是,在緩沖池裡查找abc,如果找到,指向緩沖池裡的對象,如果沒有,在緩沖池中建立abc,并指向緩沖池裡這個對象;
①②③同案例1中①②③;
④s指向堆中對象,s1指向緩沖池中的對象,故false;
⑤同理④,故false;
⑥s1和s2.intern()均指向緩沖池中的對象,并且指向的是同一個對象,故true;
案例3:
①String h = "hello";
②String e = "hel";
③String l = "lo";
④System.out.println(h == "hel" + "lo");
⑤System.out.println(h == "hel" + l);
解析:
①hello檢視緩沖池中是否存在hello,不存在,建立,并讓 h 指向緩沖池中的hello;
②hel饞看緩沖池中是否存在hel,不存在,建立,并讓e 指向緩沖池中的hel;
③lo檢視緩沖池中是否存在lo,不存在,建立,并讓 l 指向緩沖池中的 lo;
④"hel"+"lo"進行字元串連接配接,連接配接為”hello",并且檢視緩沖池中是否存在hello,①中已經在緩沖池中建立了,故直接指向hello,并且和h指向的是同一個hello,故true;
⑤hel+ l =”hello“ 但此時是在堆裡建立一個hello,并且使其指向堆中的hello,而h 是指向緩沖池中的hello,故false;
結論:+ 兩端是字面量時,在緩沖池中建立對象,如果有一端不是字面量時,而是引用變量,那麼在堆中建立對象;
《完》