2013-08-02 21 views
2

當下面的代碼寫的是:Java編譯器如何轉換包含自定義類的集合?

List<Integer> list = new ArrayList<Integer>(); 
for (int i = 1; i < 10; i++) 
list.add(i); 

Java編譯器不會發出編譯錯誤,即使我們添加的ArrayList裏面一個int,因爲它轉換(通過使用包裝類整數)到下面的代碼:

List<Integer> list = new ArrayList<Integer>(); 
for (int i = 1; i < 10; i++) 
list.add(Integer.valueOf(i)); 

然而,當我有一個自定義類,我想存儲集合中的對象會發生什麼?更具體地說,什麼鑄造操作發生,並且這些操作可以被視爲額外的開銷。

那麼,下面的代碼:

Animal animal= new Animal(); 
ArrayList<Animal> list = new ArrayList<Animal>(); 
for (int i = 1; i < 10; i++){ 
    animal.code=i; 
    list.add(animal); 
    animal= new Animal(); 
} 
Animal temp; 
for (int i = 1; i < 10; i++){ 
temp=list.get(i); 
} 

由JVM轉換爲這樣的事情:

Animal animal= new Animal(); 
ArrayList<Object> list = new ArrayList<Object>(); 
for (int i = 1; i < 10; i++){ 
    animal.id=i; 
    list.add((Object)animal); 
    animal= new Animal(); 
} 
Animal temp; 
for (int i = 1; i < 10; i++){ 
temp=(Animal)list.get(i); 
} 
+0

歡迎來到SO。好的第一個問題。要詳細瞭解泛型,請輸入erasure等,請查看:[Java泛型常見問題解答](http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html)。 –

回答

2

這種現象被稱爲type erasure。你很接近,但不是那裏。

就好像類型參數已從方法調用中移除並隱式強制類型被添加到方法返回。

ArrayList list = new ArrayList(); // The JVM sees only the raw type 

for循環之後:

list.add(animal); // No (Object) cast necessary, Animal is already implicitly an Object. 

而在第二for循環:

temp = (Animal) list.get(i); // Correct, a cast is inserted here. 

這將使用自定義類發生,如您Animal以及其他任何類型,如Integer(正如您已經指出的那樣,int將作爲Integer)。

+0

感謝您的回答。我想知道如果使用list.add(動物),拳擊被認爲是開銷。更具體地說,如果java集合的初始列表包含Animal對象而不是Object對象,那麼它是否會有任何性能差異,因爲我認爲裝箱不是必需的? – karakalos10

+1

沒有'list.add(動物)'的拳擊。 [拳擊特指將原始值放入包裝對象中](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7),並且它不是一個強制類型:'int'到'Integer','double'到'Double'等等。沒有'list.add(animal)'的開銷,因爲JVM已經將'animal'視爲'Object' ;這裏沒有演員。 – rgettman

+0

好的,非常感謝。我對此一無所知,現在很清楚。 – karakalos10

相關問題