Пример кода:
import java.util.*;
public class Foo {
public static void main() {
Foo foo = new Foo();
Object obj = new Object();
foo.f();
ArrayList<Foo> fooList = new ArrayList<Foo>();
ArrayList objList = new ArrayList();
}
public void f() {
}
}
Сформированные инструкции виртуальной машины Java (javap -c Foo
):
public class Foo {
public Foo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main();
Code:
0: new #2 // class Foo
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_0
8: new #4 // class java/lang/Object
11: dup
12: invokespecial #1 // Method java/lang/Object."<init>":()V
15: astore_1
16: aload_0
17: invokevirtual #5 // Method f:()V
20: new #6 // class java/util/ArrayList
23: dup
24: invokespecial #7 // Method java/util/ArrayList."<init>":()V
27: astore_2
28: new #6 // class java/util/ArrayList
31: dup
32: invokespecial #7 // Method java/util/ArrayList."<init>":()V
35: astore_3
36: return
public void f();
Code:
0: return
}
Как вы можете видеть, Foo foo = new Foo();
переводится на:
0: new #2 // class Foo
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_0
в то время как Object obj = new Object();
превращается в:
8: new #4 // class java/lang/Object
11: dup
12: invokespecial #1 // Method java/lang/Object."<init>":()V
15: astore_1
new
выделяет память для объекта и сохраняет ссылку в стеке, dup
создает вторую ссылку в стеке, invokespecial
вызывает конструктор (который на самом деле метод, называемый <init>
). Затем экземпляр хранится в локальной переменной с astore_1
.
Что касается ArrayList<Foo> fooList = new ArrayList<Foo>();
и ArrayList objList = new ArrayList();
, они компилировать почти то же самое:
28: new #6 // class java/util/ArrayList
31: dup
32: invokespecial #7 // Method java/util/ArrayList."<init>":()V
35: astore_3
One использует astore_2
, а другой использует astore_3
. Это потому, что они хранятся в разных локальных переменных. Помимо этого, сгенерированный код один и тот же, что означает, что JVM не может сообщить Arraylist<Foo>
от Arraylist
, что и называется стиранием типа. Тем не менее, он может очень легко сказать Foo
от Object
.
_but каждый объект просто Object._ Нет ... где вы это читали? –
@SotiriosDelimanolis См. Отредактированный – texasbruce
@SotiriosDelimanolis Путаница с типом стирания? –