Pemuat kelas
Iki digunakake kanggo nyedhiyakake bytecode sing dikompilasi menyang JVM, sing biasane disimpen ing file kanthi extension.class
, nanging uga bisa dipikolehi saka sumber liyane, contone, diundhuh liwat jaringan utawa digawe dening aplikasi kasebut dhewe. Miturut spesifikasi Java SE, supaya kode mlaku ing JVM, sampeyan kudu ngrampungake telung langkah:
-
loading bytecode saka sumber daya lan nggawe Kayata saka kelas
Class
Iki kalebu nggoleki kelas sing dijaluk ing antarane sing dimuat sadurunge, entuk bytecode kanggo dimuat lan mriksa kabeneran, nggawe conto kelas
Class
(kanggo nggarap nalika runtime), lan mbukak kelas induk. Yen kelas induk lan antarmuka durung dimuat, banjur kelas kasebut dianggep ora dimuat. -
mengikat (utawa ngubungake)
Miturut spesifikasi, tahap iki dipérang dadi telung tahap:
- Verifikasi , bener saka bytecode sing ditampa dicenthang.
- Preparation , alokasi RAM kanggo kolom statis lan initializing karo nilai gawan (ing kasus iki, initialization eksplisit, yen ana, wis ana ing tataran initialization).
- Resolusi , resolusi pranala simbolis saka jinis, kolom lan cara.
-
initializing obyek ditampa
ing kene, ora kaya paragraf sadurunge, kabeh katon jelas apa sing kudu kedadeyan. Mesthi, bakal menarik kanggo ngerti persis kepiye kedadeyan kasebut.
- Kelas kudu diisi kanthi lengkap sadurunge disambungake.
- Kelas kudu diuji lan disiapake kanthi lengkap sadurunge diwiwiti.
- Kesalahan resolusi link kedadeyan sajrone eksekusi program, sanajan dideteksi ing tahap ngubungake.
Jinis-jinis Java Loader
Ana telung loader standar ing Jawa, sing saben ngemot kelas saka lokasi tartamtu:-
Bootstrap minangka loader dhasar, uga disebut Primordial ClassLoader.
mbukak kelas JDK standar saka arsip rt.jar
-
Extension ClassLoader - extension loader.
ngemot kelas ekstensi, sing dumunung ing direktori jre/lib/ext minangka standar, nanging bisa disetel dening properti sistem java.ext.dirs
-
System ClassLoader – sistem loader.
ngemot kelas aplikasi sing ditetepake ing variabel lingkungan CLASSPATH
Kelas Abstrak ClassLoader
Saben loader, kajaba sing dhasar, minangka turunan saka kelas abstrakjava.lang.ClassLoader
. Contone, implementasine saka extension loader kelas sun.misc.Launcher$ExtClassLoader
, lan sistem loader sun.misc.Launcher$AppClassLoader
. Loader basa asli lan implementasine kalebu ing JVM. Sembarang kelas sing ngluwihi java.lang.ClassLoader
bisa nyedhiyani cara dhewe loading kelas karo blackjack lan iki padha. Kanggo nindakake iki, perlu kanggo nemtokake maneh cara sing cocog, sing saiki aku mung bisa nimbang kanthi entheng, amarga Aku ora ngerti masalah iki kanthi rinci. Punika:
package java.lang;
public abstract class ClassLoader {
public Class<?> loadClass(String name);
protected Class<?> loadClass(String name, boolean resolve);
protected final Class<?> findLoadedClass(String name);
public final ClassLoader getParent();
protected Class<?> findClass(String name);
protected final void resolveClass(Class<?> c);
}
loadClass(String name)
salah siji saka sawetara cara umum, kang titik entri kanggo loading kelas. Implementasine boils mudhun kanggo nelpon cara liyane sing dilindhungi loadClass(String name, boolean resolve)
, kang kudu overridden. Yen katon ing Javadoc saka cara sing dilindhungi iki, sampeyan bisa ngerti kaya ing ngisor iki: loro paramèter diwenehake minangka input. Salah sijine yaiku jeneng binar kelas (utawa jeneng kelas sing mumpuni) sing kudu dimuat. Jeneng kelas kasebut kanthi dhaptar kabeh paket. Parameter kapindho yaiku gendera sing nemtokake manawa resolusi link simbolis dibutuhake. Kanthi gawan iku palsu , kang tegese loading kelas puguh digunakake. Sabanjure, miturut dokumentasi, ing implementasine standar metode kasebut ana telpon findLoadedClass(String name)
sing mriksa manawa kelas kasebut wis dimuat sadurunge lan, yen mangkono, ngasilake referensi menyang kelas iki. Yen ora, metode loading kelas saka loader induk bakal diarani. Yen ora ana loader bisa nemokake kelas dimuat, saben wong, ing urutan mbalikke, bakal nyoba kanggo nemokake lan mbukak kelas sing, overriding ing findClass(String name)
. Iki bakal dibahas kanthi luwih rinci ing bab "Skema Loading Kelas". Lan pungkasanipun, pungkasan nanging paling ora, sawise kelas wis dimuat, gumantung ing flag mutusake masalah , bakal mutusaké apa arep mbukak kelas liwat pranala simbolis. Conto sing jelas yaiku tahap Resolusi bisa diarani nalika tahap loading kelas. Mulane, kanthi ngluwihi kelas ClassLoader
lan ngatasi cara, loader khusus bisa ngetrapake logika dhewe kanggo ngirim bytecode menyang mesin virtual. Jawa uga ndhukung konsep loader kelas "saiki". Loader saiki yaiku sing ngemot kelas sing saiki dieksekusi. Saben kelas ngerti loader kang dimuat karo, lan sampeyan bisa njaluk informasi iki dening nelpon sawijining String.class.getClassLoader()
. Kanggo kabeh kelas aplikasi, loader "saiki" biasane dadi sistem.
Telung Prinsip Pemuatan Kelas
-
Delegasi
Panjaluk kanggo mbukak kelas diterusake menyang loader induk, lan nyoba mbukak kelas kasebut mung yen loader induk ora bisa nemokake lan mbukak kelas kasebut. Pendekatan iki ngidini sampeyan mbukak kelas kanthi loader sing paling cedhak karo pangkalan. Iki entuk visibilitas kelas maksimal. Saben loader nyimpen rekaman kelas sing dimuat, diselehake ing cache. Sakumpulan kelas kasebut diarani ruang lingkup.
-
Visibilitas
Loader mung ndeleng kelas "sawijining" lan kelas "wong tuwa" lan ora ngerti babagan kelas sing dimuat dening "anak".
-
Keunikan
Kelas mung bisa dimuat sapisan. Mekanisme delegasi nggawe manawa loader sing miwiti loading kelas ora kakehan kelas sing sadurunge dimuat menyang JVM.
Skema pengisian kelas
Nalika ana telpon kanggo mbukak kelas, kelas iki digoleki ing cache kelas sing wis dimuat saka loader saiki. Yen kelas sing dikarepake durung dimuat sadurunge, prinsip delegasi nransfer kontrol menyang loader induk, sing dumunung ing siji tingkat sing luwih dhuwur ing hirarki. Loader induk uga nyoba nemokake kelas sing dikarepake ing cache. Yen kelas wis dimuat lan loader ngerti lokasi, banjur obyekClass
saka kelas bakal bali. Yen ora, panelusuran bakal terus nganti tekan bootloader dhasar. Yen base loader ora duwe informasi babagan kelas sing dibutuhake (yaiku, durung dimuat), bytecode kelas iki bakal digoleki ing lokasi kelas sing diweruhi loader, lan yen kelas kasebut ora bisa. dimuat, kontrol bakal bali menyang loader anak, kang bakal nyoba kanggo mbukak saka sumber dikenal kanggo iku. Kaya kasebut ing ndhuwur, lokasi kelas kanggo basa loader perpustakaan rt.jar, kanggo extension loader - direktori karo jre / lib / ekstensi ext, kanggo sistem siji - CLASSPATH, kanggo pangguna siji bisa soko beda. . Mangkono, kemajuan kelas loading ing arah ngelawan - saka loader ROOT kanggo saiki. Nalika bytecode saka kelas ketemu, kelas dimuat menyang JVM lan Kayata saka jinis dijupuk Class
. Nalika sampeyan bisa ndeleng kanthi gampang, skema loading sing diterangake padha karo implementasine metode kasebut ing ndhuwur loadClass(String name)
. Ing ngisor iki sampeyan bisa ndeleng diagram iki ing diagram.
Minangka kesimpulan
Ing langkah pisanan sinau basa, ora perlu ngerti carane kelas dimuat ing Jawa, nanging ngerti prinsip dhasar iki bakal mbantu sampeyan supaya ora kentekan niat nalika nemoni kesalahan kayataClassNotFoundException
utawa NoClassDefFoundError
. Inggih, utawa paling ora ngerti apa oyot masalah kasebut. Mangkono, pangecualian ClassNotFoundException
occurs nalika kelas wis mbosenke dimuat sak eksekusi program, nalika loaders ora bisa nemokake kelas dibutuhake salah siji ing cache utawa ing path kelas. Nanging kesalahan kasebut NoClassDefFoundError
luwih kritis lan kedadeyan nalika kelas sing dibutuhake kasedhiya sajrone kompilasi, nanging ora katon sajrone eksekusi program. Iki bisa kedadeyan yen program kelalen nyakup perpustakaan sing digunakake. Inggih, kasunyatan banget kanggo mangerteni prinsip struktur alat sing sampeyan gunakake ing karya sampeyan (ora mesthi kecemplung sing jelas lan rinci ing jerone) nambah kajelasan babagan proses sing kedadeyan ing mekanisme iki, sing, ing giliran, ndadékaké kanggo nggunakake manteb ing ati saka alat iki.
GO TO FULL VERSION