Perbezaan antara Class.forName dan ClassLoader.loadClass
Pemuatan kelas
Untuk memahami perbezaan antara Class.forName dan ClassLoader.loadClass, mula-mula kita perlu memahami langkah-langkah pemuatan kelas dalam JVM Pemuatan kelas boleh dibahagikan kepada langkah-langkah berikut
Memuatkan: Dapatkan strim binari kelas melalui nama yang layak sepenuhnya, dan kemudian muatkannya ke dalam JVM
Pengesahan: Pastikan maklumat yang terkandung dalam aliran bait fail Kelas memenuhi keperluan mesin maya dan tidak akan membahayakan keselamatan mesin maya
Persediaan: Peruntukkan ruang memori untuk pembolehubah kelas dan tetapkan nilai awal pembolehubah kelas
Analisis
Permulaan: Memulakan medan dan sumber lain mengikut kod yang ditentukan pengguna, melaksanakan blok statik.
Kelas.untukNama
Apabila kita lulus:
Class.forName("com.test.MyObj")
Apabila
digunakan untuk mendapatkan Kelas, ia sebenarnya bersamaan dengan memanggil Class.forName(className, true, currentLoader) Parameter kedua kaedah ini menunjukkan sama ada kelas itu perlu dimulakan kepada true, jadi apabila Class.forName memperoleh objek Kelas, ia akan Kelas dimulakan secara automatik. Dan ClassLoader kelas yang dimuatkan oleh Class.forName adalah sama dengan ClassLoader kelas di mana Class.forName dipanggil.
ClassLoader.loadClass
berbeza daripada Class.forName Secara lalai, ClassLoader.loadClass tidak memulakan kelas, iaitu, langkah 初始化 pemuatan kelas tidak dilaksanakan, jadi blok kod statik dalam kelas tidak akan dilaksanakan. dan gunakan ClassLoader.loadClass, kita boleh menentukan ClassLoader yang berbeza Contohnya:
public class MyObj {
static {
System.out.println("MyObj class init.");
}
}
public class Test implements Cloneable, Serializable {
public static void main(String[] args) throws Exception {
Class.forName("com.test.MyObj");
// ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
}
}
Dalam kod di atas, panggilan Class.forName("com.test.MyObj") akan mencetuskan pelaksanaan blok kod statik MyObj, tetapi ClassLoader.getSystemClassLoader().loadClass("com.test.MyObj"); tidak.
Apakah faedah menggunakannya dengan cara ini?
Tekaan peribadi saya ialah ia harus berkaitan dengan pemuatan Lazy Spring IoC Untuk mempercepatkan pemulaan, Spring IoC menggunakan banyak teknologi pemuatan tertunda menggunakan pemuat kelas tidak perlu melaksanakan kod pemulaan dalam kelas. yang boleh mempercepatkan pemuatan. Kerja permulaan kelas dibiarkan sehingga kelas itu benar-benar digunakan.
Perbezaan antara Class.forName dan ClassLoader.loadClass
Pemuatan kelas
Untuk memahami perbezaan antara
Class.forName
danClassLoader.loadClass
, mula-mula kita perlu memahami langkah-langkah pemuatan kelas dalam JVMPemuatan kelas boleh dibahagikan kepada langkah-langkah berikut
Memuatkan: Dapatkan strim binari kelas melalui nama yang layak sepenuhnya, dan kemudian muatkannya ke dalam JVM
Pengesahan: Pastikan maklumat yang terkandung dalam aliran bait fail Kelas memenuhi keperluan mesin maya dan tidak akan membahayakan keselamatan mesin maya
Persediaan: Peruntukkan ruang memori untuk pembolehubah kelas dan tetapkan nilai awal pembolehubah kelas
Analisis
Permulaan: Memulakan medan dan sumber lain mengikut kod yang ditentukan pengguna, melaksanakan blok statik.
Kelas.untukNama
Apabila kita lulus:
Apabiladigunakan untuk mendapatkan Kelas, ia sebenarnya bersamaan dengan memanggil
Class.forName(className, true, currentLoader)
Parameter kedua kaedah ini menunjukkan sama ada kelas itu perlu dimulakan kepadatrue
, jadi apabila Class.forName memperoleh objek Kelas, ia akan Kelas dimulakan secara automatik.Dan ClassLoader kelas yang dimuatkan oleh Class.forName adalah sama dengan ClassLoader kelas di mana
Class.forName
dipanggil.ClassLoader.loadClass
berbeza daripada
Class.forName
Secara lalai,ClassLoader.loadClass
tidak memulakan kelas, iaitu, langkah初始化
pemuatan kelas tidak dilaksanakan, jadi blok kod statik dalam kelas tidak akan dilaksanakan.dan gunakan
ClassLoader.loadClass
, kita boleh menentukan ClassLoader yang berbeza Contohnya:Contoh
Dalam kod di atas, panggilan
Class.forName("com.test.MyObj")
akan mencetuskan pelaksanaan blok kod statik MyObj, tetapiClassLoader.getSystemClassLoader().loadClass("com.test.MyObj");
tidak.Apakah faedah menggunakannya dengan cara ini?
Tekaan peribadi saya ialah ia harus berkaitan dengan pemuatan Lazy Spring IoC Untuk mempercepatkan pemulaan, Spring IoC menggunakan banyak teknologi pemuatan tertunda menggunakan pemuat kelas tidak perlu melaksanakan kod pemulaan dalam kelas. yang boleh mempercepatkan pemuatan. Kerja permulaan kelas dibiarkan sehingga kelas itu benar-benar digunakan.