dan Kaedah dalam JVM

1. Gambaran keseluruhan

JVM menggunakan dua kaedah khas untuk memulakan keadaan dan kelas objek.

Dalam artikel ringkas ini, kita akan melihat bagaimana penyusun dan waktu proses menggunakan dan kaedah untuk tujuan permulaan.

2. Kaedah Permulaan Permulaan

Mari kita mulakan dengan peruntukan dan tugasan objek langsung:

Object obj = new Object();

Sekiranya kita menyusun coretan ini dan melihat kod bytecnya melalui javap -c , kita akan melihat seperti:

0: new #2 // class java/lang/Object 3: dup 4: invokespecial #1 // Method java/lang/Object."":()V 7: astore_1

Untuk memulakan objek , JVM memanggil kaedah khas yang dinamakan .Dalam jargon JVM, kaedah ini adalah kaedah inisialisasi contoh . Kaedah adalah permulaan contoh jika dan hanya jika:

  • Ia ditakrifkan dalam kelas
  • Namanya < init>
  • Ia kembali terbatal

Setiap kelas boleh mempunyai kaedah permulaan permulaan sifar atau lebih . Kaedah ini biasanya sesuai dengan konstruktor dalam bahasa pengaturcaraan berasaskan JVM seperti Java atau Kotlin.

2.1. Blok Pembina dan Pembina Contoh

Untuk lebih memahami bagaimana penyusun Java menerjemahkan konstruktor ke , mari kita pertimbangkan contoh lain:

public class Person { private String firstName = "Foo"; //  private String lastName = "Bar"; //  //  { System.out.println("Initializing..."); } //  public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } //  public Person() { } }

Ini adalah bytecode untuk kelas ini:

public Person(java.lang.String, java.lang.String); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: aload_0 5: ldc #7 // String Foo 7: putfield #9 // Field firstName:Ljava/lang/String; 10: aload_0 11: ldc #15 // String Bar 13: putfield #17 // Field lastName:Ljava/lang/String; 16: getstatic #20 // Field java/lang/System.out:Ljava/io/PrintStream; 19: ldc #26 // String Initializing... 21: invokevirtual #28 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 24: aload_0 25: aload_1 26: putfield #9 // Field firstName:Ljava/lang/String; 29: aload_0 30: aload_2 31: putfield #17 // Field lastName:Ljava/lang/String; 34: return

Walaupun blok konstruktor dan penginisialisasi terpisah di Java, mereka berada dalam kaedah inisialisasi contoh yang sama pada tahap bytecode. Sebenarnya, inikaedah:

  • Pertama, memulakan medan nama pertama dan nama akhir (indeks 0 hingga 13)
  • Kemudian, ia mencetak sesuatu ke konsol sebagai sebahagian daripada blok pemula contoh (indeks 16 hingga 21)
  • Dan akhirnya, ia mengemas kini pemboleh ubah contoh dengan argumen pembina

Sekiranya kita membuat Orang seperti berikut:

Person person = new Person("Brian", "Goetz");

Kemudian ini diterjemahkan kepada kod bytek berikut:

0: new #7 // class Person 3: dup 4: ldc #9 // String Brian 6: ldc #11 // String Goetz 8: invokespecial #13 // Method Person."":(Ljava/lang/String;Ljava/lang/String;)V 11: astore_1

Kali ini JVM memanggil yang lain kaedah dengan tandatangan yang sesuai dengan pembina Java.

Perhatian utama di sini adalah bahawa pembina dan pemula contoh lain setara dengan kaedah dalam dunia JVM.

3. Kaedah Permulaan Kelas

Di Java, blok inisialisasi statik berguna ketika kita akan menginisialisasi sesuatu di peringkat kelas:

public class Person { private static final Logger LOGGER = LoggerFactory.getLogger(Person.class); //  //  static { System.out.println("Static Initializing..."); } // omitted }

Apabila kita menyusun kod sebelumnya, pengkompil menerjemahkan blok statik ke kaedah inisialisasi kelas pada tahap bytecode.

Sederhananya, kaedah adalah permulaan kelas jika dan hanya jika:

  • Namanya ialah
  • Ia kembali terbatal

Oleh itu, satu-satunya cara untuk menghasilkan a kaedah di Java adalah menggunakan medan statik dan pemula blok statik.

JVM memohon kali pertama kami menggunakan kelas yang sesuai. Oleh itu,pemohon berlaku pada waktu runtime, dan kita tidak dapat melihat pemanggilan pada tahap bytecode.

4. Kesimpulan

Dalam artikel ringkas ini, kami melihat perbezaan antara dan kaedah dalam JVM. Thekaedah digunakan untuk memulakan kejadian objek. Juga, JVM memohonkaedah untuk memulakan kelas bila perlu.

Untuk lebih memahami bagaimana inisialisasi berfungsi di JVM, sangat disarankan untuk membaca spesifikasi JVM.