2014-01-22 90 views
3
String summer = new String("Summer"); 
String summer2 = "Summer"; 
System.out.println("Summer"); 
System.out.println("autumn"); 
System.out.println("autumn" == "summer"); 
String autumn = new String("Summer"); 

我的回答是2 + 0 + 0 + 1 + 1 + 1 = 5。這是對的嗎?爲以下內容創建了多少個字符串對象?

+0

我想這將只有3. – Anubhab

+1

它不能是2 ,因爲這裏至少有*三個不同的字符串... – Makoto

+0

@Makoto'String summer2 =「Summer」;'是一個字符串字面值。 – Maroun

回答

5

對我來說聽起來很合理。

String summer = new String("Summer"); 

創建2個實例。首先是文字"Summer"。第二個是因爲構造函數被調用。

String summer2 = "Summer"; 

0例:這只是一個參考作業。

System.out.println("Summer"); 

0個實例。文字"Summer"取自緩存。

System.out.println("autumn"); 

1實例"autumn"

System.out.println("autumn" == "summer"); 

1實例"summer"

String autumn = new String("Summer"); 

1實例引起構造函數調用。文字"Summer"取自緩存。

底線:2 + 0 + 0 + 1 + 1 + 1 = 5

+2

在Java 7中,它根據需要創建字符串文字,但在Java 6中,它在類加載時完成,這可能會改變您的答案。 –

+0

答案不應該小於5嗎?在不創建新實例的情況下,但是在字符串池中繼續的情況下,這不僅僅是一種未定義行爲的編譯器優化嗎?我沒有想到這種行爲被記錄或要求用於Java編譯器。 – kba

+0

@Peter Lawrey,我不知道java 6和7之間的這種區別。你能解釋更多還是發送一些鏈接? – AlexR

1

是的,這是正確的。總共有5個對象將被創建。

String summer = new String("Summer"); // 2 objects. One for constructor and other for literal 
String summer2 = "Summer"; // 0. Will point to the literal already created. 
System.out.println("Summer"); // 0. Same as above statement 
System.out.println("autumn"); // 1 object will be created 
System.out.println("autumn" == "summer"); // 1 object. 'Summer' and 'summer' are not same 
String autumn = new String("Summer"); // 1 object. new String() will cause a new object creation but not the literal 
1

編譯並計數:

import java.lang.reflect.Field; 
import sun.misc.Unsafe; 
public class test { 
    private static Unsafe unsafe; 

    static { 
     try { 
      Field field = Unsafe.class.getDeclaredField("theUnsafe"); 
      field.setAccessible(true); 
      unsafe = (Unsafe) field.get(null); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static long addressOf(Object o) throws Exception { 
     Object[] array = new Object[]{o}; 

     long baseOffset = unsafe.arrayBaseOffset(Object[].class); 
     int addressSize = unsafe.addressSize(); 
     long objectAddress; 
     switch (addressSize) { 
      case 4: 
       objectAddress = unsafe.getInt(array, baseOffset); 
       break; 
      case 8: 
       objectAddress = unsafe.getLong(array, baseOffset); 
       break; 
      default: 
       throw new Error("unsupported address size: " + addressSize); 
     } 

     return (objectAddress); 
    } 

    public static void main(String... args) 
      throws Exception { 

     String summer = new String("Summer"); 
     System.out.println("Addess: " + addressOf(summer)); 
     String summer2 = "Summer"; 
     System.out.println("Addess: " + addressOf(summer2)); 
     System.out.println("Addess: " + addressOf("Summer")); 
     System.out.println("Addess: " + addressOf("autumn")); 
     System.out.println("Addess: " + addressOf("autumn")); 
     System.out.println("Addess: " + addressOf("summer")); 
     //System.out.println("Summer"); 
     //System.out.println("autumn"); 
     //System.out.println("autumn" == "summer"); 
     String autumn = new String("Summer"); 
     System.out.println("Addess: " + addressOf(autumn)); 


    } 

    public static void printBytes(long objectAddress, int num) { 
     for (long i = 0; i < num; i++) { 
      int cur = unsafe.getByte(objectAddress + i); 
      System.out.print((char) cur); 
     } 
     System.out.println(); 
    } 
}