2014-10-04 76 views
3

我看過這篇文章:Is int an object in Java?如果int不繼承Object,那麼爲什麼「String.format(String,Object ...)」用int的編譯?

在帖子中,有人認爲int不是從Object繼承。如果是這樣的話,那麼爲什麼下面的代碼沒有任何錯誤編譯?鑑於int不是Objectformat()方法的簽名是public static String format(String format, Object... args)如文檔所示:javadoc for String

public class Testing { 
    public static void main(String[] args) { 
     int integer = 7; 
     String str = String.format("%03d", integer); 
     System.out.println(str); 
    } 
} 

我也讀過關於「自動裝箱」的內容。這究竟意味着什麼?在編譯之前所有的原語是否被合適的Object所取代?如果是這樣,那麼在Integer的(Integer[])上使用大量的intint[])時,是否有任何內存使用優勢?類似的論點遵循雙等。

任何見解是值得歡迎的。

回答

3

當調用String.format("%d",myInt)myInt自然而然(隱含地),因此它編譯。

關於陣列,由於某些原因,從primitiveType[]WrapperClass[]的轉換不是自動的。如果您嘗試使用包裝類的數組需要的基本類型的數組,它將導致編譯錯誤。

與使用int相比,使用Integer會產生開銷,因爲您需要分配和存儲引用。但是,當在-128和127之間使用Integer值時,這種開銷是有限的,因爲這些值是合併的(這意味着Integer的所有實例在此間隔中指向單向引用)。

+0

感謝您的回答,並感謝您澄清我對數組的懷疑。我從你的和其他答案中得出的結論是,自動裝箱是在需要時在本地完成的,因此int []將比Integer []需要更少的空間。你能否詳細說明最後的聲明。你的意思是,如果Integer中包含的值介於-128和127之間,則不使用引用? – 2014-10-04 09:39:56

+0

在實例化-128和127之間的Integer時,如果該值已存在於池中,則JVM將首先在整數池中查找。如果有,則返回包含此值的現有Integer的引用,否則將創建一個新的Integer,將其添加到池中並返回。它使我們能夠減少Integer引用的數量,因爲大部分時間我們使用低整數值而不是高值。 – Dici 2014-10-04 12:09:59

+0

你可以閱讀這個問題的3個第一個答案的一部分,以更好的方式解釋它:http://stackoverflow.com/questions/13098143/java-integer-constant-pool – Dici 2014-10-04 12:14:06

3

自動裝箱是從編譯器,它會自動編譯像

foo(i); 

foo(Integer.valueOf(i)); 

foo()使用對象類型作爲自變量的幫助,你傳遞一個基本類型(INT,在這種情況下)。它只是讓代碼更容易打字和閱讀。

而這就是發生在這裏。 String.format()方法需要將對象作爲參數。你將它傳遞給一個原始類型,所以編譯器會自動將它自動包裝爲一個Integer。

+0

謝謝你的回答。 – 2014-10-04 09:47:50

5

它是由Autoboxing造成的。

這裏是鏈接Java文檔一個小片段,說明它不是更好,我可以:

自動裝箱是自動轉換,Java編譯器,使 基本類型及其相應的對象包裝 類之間。例如,將int轉換爲整數,雙精度轉換爲雙精度,等等。如果轉換以其他方式進行,則這是 稱爲取消裝箱。

下面是自動裝箱的最簡單的例子:

Character ch = 'a'; 

的本節中使用泛型實施例中的其餘部分。如果您不是 但仍然熟悉泛型語法,請參閱泛型(更新) 課程。

考慮下面的代碼:

List<Integer> li = new ArrayList<>(); 
for (int i = 1; i < 50; i += 2) 
    li.add(i); 

雖然你加INT值作爲原始類型,而不是 Integer對象,李,代碼編譯。因爲li是整數對象列表 ,而不是int值列表,所以您可能想知道爲何Java 編譯器不會發出編譯時錯誤。編譯器不會 生成一個錯誤,因爲它會從i創建一個Integer對象,並將該對象添加到li中。因此,編譯器轉換之前的代碼到 在運行時執行以下操作:包裝在一個Integer實例,它延伸Object

List<Integer> li = new ArrayList<>(); 
for (int i = 1; i < 50; i += 2) 
    li.add(Integer.valueOf(i)); 
+0

謝謝你的回答。 – 2014-10-04 09:48:07