Saya percaya bahawa ramai pelajar telah menemui soalan seperti ini. Mereka mungkin telah mencari maklumat itu dan kemudian terlupa jika mereka menemuinya lagi, mereka masih tidak dapat menjawabnya dengan betul. Seterusnya, melalui 4 langkah, saya akan membawa anda untuk membuka urutan pelaksanaan kod ini dan meringkaskan peraturan.
Soalan pembukaan untuk mengkaji susunan pelaksanaan kod:
public class Parent { static { System.out.println("Parent static initial block"); } { System.out.println("Parent initial block"); } public Parent() { System.out.println("Parent constructor block"); } } public class Child extends Parent { static { System.out.println("Child static initial block"); } { System.out.println("Child initial block"); } private Hobby hobby = new Hobby(); public Child() { System.out.println("Child constructor block"); } } public class Hobby { static{ System.out.println("Hobby static initial block"); } public Hobby() { System.out.println("hobby constructor block"); } }
Apabila Child() baharu dilaksanakan, apakah yang dikeluarkan oleh kod di atas?
Saya percaya ramai pelajar yang menghadapi masalah sebegini mungkin telah menyemak maklumat tersebut dan kemudiannya terlupa jika terjumpa lagi, mereka masih tidak dapat menjawabnya dengan betul. Seterusnya, wakil kelas akan membawa anda melalui 4 langkah untuk merungkai urutan pelaksanaan kod ini dan meringkaskan peraturan.
Dua keping kod berikut membandingkan perubahan sebelum dan selepas penyusunan:
Child.java sebelum penyusunan
public class Child extends Parent { static { System.out.println("Child static initial block"); } { System.out.println("Child initial block"); } private Hobby hobby = new Hobby(); public Child() { System.out.println("Child constructor block"); } }
Child.class selepas kompilasi
public class Child extends Parent { private Hobby hobby; public Child() { System.out.println("Child initial block"); this.hobby = new Hobby(); System.out.println("Child constructor block"); } static { System.out.println("Child static initial block"); } }
Ia boleh dilihat daripada perbandingan bahawa pengkompil mengalihkan blok permulaan dan operasi penetapan medan contoh sebelum kod pembina, dan mengekalkan susunan kod yang berkaitan. Malah, jika terdapat berbilang pembina, kod permulaan akan disalin dan dipindahkan.
Berdasarkan ini, susunan keutamaan pertama boleh diperolehi:
Kod statik kelas induk> Kod statik subkelas
3 Kod statik hanya dilaksanakan sekali Kita semua tahu bahawa kod statik (kecuali kaedah statik) hanya dilaksanakan sekali.Dengan ulasan, saya percaya ia mudah difahami oleh semua orang.
Ia boleh dilihat daripada kod yang diwakilkan oleh ibu bapa bahawa di bawah pemuat kelas yang sama, kelas hanya boleh dimuatkan sekali, yang mengehadkannya kepada hanya dimulakan sekali. Oleh itu, kod statik dalam kelas (kecuali kaedah statik) hanya dilaksanakan sekali apabila kelas dimulakan
4 <init>
Kod yang dijana secara automatik oleh pengkompil telah diperkenalkan sebelum Pembina Kelas: kaedah <clinit> ia akan mengumpulkan tindakan tugasan dan blok pernyataan statik (blok{} statik) semua pembolehubah kelas yang diubah suai statik dan mengekalkan susunan penampilan kod itu dilaksanakan apabila kelas dimulakan
Sehubungan itu, pengkompil juga akan menjana kaedah <init> yang akan mengumpul tindakan tugasan medan contoh, kod dalam blok pernyataan permulaan ({}) dan pembina (Pembina), dan mengekalkan susunan kemunculan kod , ia akan melaksanakan
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // 首先检查该类是否被加载过 // 如果加载过,直接返回该类 Class<?> c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // 如果父类抛出ClassNotFoundException // 说明父类无法完成加载请求 } if (c == null) { // 如果父类无法加载,转由子类加载 c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
1 Kod statik (blok{} statik, pernyataan tugasan medan statik) > Kod pembina
2. Kod statik kelas induk > Kod statik subkelas
Menurut ringkasan sebelumnya, kod permulaan dan kod pembina dikumpul oleh pengkompil <init> kod statik dikumpulkan ke dalam <clinit>, jadi peraturan di atas digabungkan semula:
Kelas induk
> Kelas induk > 🎜><clinit>
Sesuai dengan soalan pada mulanya, mari kita praktikkannya: <clinit>
<init>
Apabila melaksanakan Child() baharu, kata kunci baharu mencetuskan permulaan kelas Child dan JVM mendapati ia mempunyai induk kelas , kemudian mulakan kelas Induk dahulu, mula melaksanakan kaedah <clinit> kelas Induk, dan kemudian laksanakan kaedah <clinit> kelas Anak (ingat apa yang dikumpul dalam <clinit>?). <init>
Atas ialah kandungan terperinci Membolehkan anda memahami kata kunci statik dalam Java sekaligus. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!