JavaRush /Blog Jawa /Random-JV /Carane kelas dimuat menyang JVM
Aleksandr Zimin
tingkat
Санкт-Петербург

Carane kelas dimuat menyang JVM

Diterbitake ing grup
Sawise bagean paling angel saka karya programmer wis rampung lan aplikasi "Hello World 2.0" wis ditulis, sing isih ana yaiku ngumpulake kit distribusi lan ngirim menyang pelanggan, utawa paling ora menyang layanan testing. Ing distribusi, kabeh kaya sing dikarepake, lan nalika kita miwiti program, Mesin Virtual Java teka ing adegan. Iku ora rahasia sing mesin virtual maca printah presented ing file kelas ing wangun bytecode lan nerjemahake minangka instruksi kanggo prosesor. Aku propose kanggo ngerti sethitik babagan rencana bytecode njaluk menyang mesin virtual.

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. Kepiye kelas dimuat ing JVM - 1Miturut spesifikasi Java SE, supaya kode mlaku ing JVM, sampeyan kudu ngrampungake telung langkah:
  • loading bytecode saka sumber daya lan nggawe Kayata saka kelasClass

    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.

Kabeh langkah kasebut ditindakake kanthi urutan kanthi syarat ing ngisor iki:
  • 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.
Kaya sing sampeyan ngerteni, Java ngleksanakake lazy (utawa kesed) loading kelas. Iki tegese ngemot kelas kolom referensi kelas sing dimuat ora bakal ditindakake nganti aplikasi kasebut nemoni referensi sing jelas. Ing tembung liya, ngrampungake pranala simbolis iku opsional lan ora kedadeyan minangka standar. Nanging, implementasine JVM uga bisa nggunakake loading kelas energik, i.e. kabeh pranala simbolis kudu dijupuk menyang akun langsung. Kanggo titik iki sing syarat pungkasan ditrapake. Sampeyan uga kudu dicathet yen resolusi pranala simbolis ora ana gandhengane karo tahapan loading kelas. Umumé, saben tahapan kasebut nggawe sinau sing apik; ayo goleki sing pertama, yaiku ngemot bytecode.

Jinis-jinis Java Loader

Ana telung loader standar ing Jawa, sing saben ngemot kelas saka lokasi tartamtu:
  1. Bootstrap minangka loader dhasar, uga disebut Primordial ClassLoader.

    mbukak kelas JDK standar saka arsip rt.jar

  2. 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

  3. System ClassLoader – sistem loader.

    ngemot kelas aplikasi sing ditetepake ing variabel lingkungan CLASSPATH

Jawa nggunakake hirarki loader kelas, ngendi ROOT, mesthi, basis. Sabanjure ana extension loader, lan banjur sistem loader. Alami, saben loader nyimpen pointer menyang wong tuwa supaya bisa utusan loading yen dheweke ora bisa nindakake iki.

Kelas Abstrak ClassLoader

Saben loader, kajaba sing dhasar, minangka turunan saka kelas abstrak java.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.ClassLoaderbisa 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 ClassLoaderlan 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.

Dadi, nalika nulis bootloader, pangembang kudu dipandu dening telung prinsip kasebut.

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 obyek Classsaka 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.
Kepiye kelas dimuat ing JVM - 2

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 kayata ClassNotFoundExceptionutawa NoClassDefFoundError. Inggih, utawa paling ora ngerti apa oyot masalah kasebut. Mangkono, pangecualian ClassNotFoundExceptionoccurs 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 NoClassDefFoundErrorluwih 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.

Sumber

Carane ClassLoader Works in Java Sakabèhé sumber banget migunani karo presentation diakses informasi. Loading kelas, ClassLoader Cukup artikel dawa, nanging karo emphasis carane nggawe implementasine loader dhewe karo iki padha. ClassLoader: loading dinamis saka kelas Sayange, sumber iki ora kasedhiya saiki, nanging ana aku ketemu diagram paling dingerteni karo rencana loading kelas, supaya aku ora bisa bantuan nanging nambah. Spesifikasi Java SE: Bab 5. Loading, Linking, and Initializing
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION