Sinf yuklagichi
U JVM ga kompilyatsiya qilingan bayt kodini etkazib berish uchun ishlatiladi, u odatda kengaytmali fayllarda saqlanadi.class
, lekin boshqa manbalardan ham olinishi mumkin, masalan, tarmoq orqali yuklab olingan yoki dasturning o'zi tomonidan yaratilgan. Java SE spetsifikatsiyasiga ko'ra, JVM-da ishlaydigan kodni olish uchun siz uchta bosqichni bajarishingiz kerak:
-
resurslardan bayt kodini yuklash va sinfning namunasini yaratish
Class
Bunga avvalroq yuklanganlar orasida soʻralgan sinfni qidirish, yuklash uchun bayt-kodni olish va uning toʻgʻriligini tekshirish, sinf namunasini yaratish
Class
(ish vaqtida u bilan ishlash uchun) va ota-sinflarni yuklash kiradi. Agar ota-sinflar va interfeyslar yuklanmagan bo'lsa, ko'rib chiqilayotgan sinf yuklanmagan deb hisoblanadi. -
bog'lash (yoki bog'lash)
Spetsifikatsiyaga ko'ra, bu bosqich yana uchta bosqichga bo'lingan:
- Tekshirish , qabul qilingan bayt kodining to'g'riligi tekshiriladi.
- Tayyorlash , statik maydonlar uchun RAMni ajratish va ularni standart qiymatlar bilan ishga tushirish (bu holda, agar mavjud bo'lsa, aniq ishga tushirish allaqachon ishga tushirish bosqichida sodir bo'ladi).
- Rezolyutsiya , turlar, maydonlar va usullarning ramziy bog'lanishlarini hal qilish.
-
qabul qilingan ob'ektni ishga tushirish
bu erda, oldingi paragraflardan farqli o'laroq, hamma narsa nima bo'lishi kerakligi aniq ko'rinadi. Albatta, bu qanday sodir bo'lishini tushunish qiziq.
- Ulanishdan oldin sinf toʻliq yuklangan boʻlishi kerak.
- Sinf to'liq sinovdan o'tkazilishi va ishga tushirilishidan oldin tayyorlanishi kerak.
- Bog'lanishni aniqlashda xatoliklar, hatto ulanish bosqichida aniqlangan bo'lsa ham, dasturni bajarish paytida yuzaga keladi.
Java yuklagichlarining turlari
Java-da uchta standart yuklagich mavjud bo'lib, ularning har biri ma'lum bir joydan sinfni yuklaydi:-
Bootstrap - bu asosiy yuklovchi bo'lib, u Primordial ClassLoader deb ham ataladi.
rt.jar arxividan standart JDK sinflarini yuklaydi
-
Extension ClassLoader - kengaytmali yuklovchi.
sukut bo'yicha jre/lib/ext katalogida joylashgan kengaytma sinflarini yuklaydi, lekin java.ext.dirs tizim xususiyati tomonidan o'rnatilishi mumkin.
-
System ClassLoader - tizim yuklagichi.
CLASSPATH muhit o'zgaruvchisida belgilangan dastur sinflarini yuklaydi
Abstrakt sinf ClassLoader
Har bir yuklovchi, asosiysidan tashqari, mavhum sinfning avlodidirjava.lang.ClassLoader
. Masalan, kengaytmali yuklovchining amalga oshirilishi sinf sun.misc.Launcher$ExtClassLoader
, tizim yuklagichi esa sun.misc.Launcher$AppClassLoader
. Asosiy yuklovchi mahalliy bo'lib, uni amalga oshirish JVMga kiritilgan. Kengaytirilgan har qanday sinf java.lang.ClassLoader
blackjack va shu kabilar bilan sinflarni yuklashning o'ziga xos usulini taqdim etishi mumkin. Buni amalga oshirish uchun tegishli usullarni qayta belgilash kerak, ularni hozirda faqat yuzaki ko'rib chiqish mumkin, chunki Men bu masalani batafsil tushunmadim. Mana ular:
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)
sinflarni yuklash uchun kirish nuqtasi bo'lgan bir nechta ommaviy usullardan biri. Uni amalga oshirish boshqa himoyalangan usulni chaqirish bilan tugaydi loadClass(String name, boolean resolve)
, uni bekor qilish kerak. Agar siz ushbu himoyalangan usulning Javadoc-ga qarasangiz, quyidagi kabi narsalarni tushunishingiz mumkin: ikkita parametr kirish sifatida taqdim etiladi. Ulardan biri yuklanishi kerak bo'lgan sinfning ikkilik nomi (yoki to'liq malakali sinf nomi). Sinf nomi barcha paketlar ro'yxati bilan ko'rsatilgan. Ikkinchi parametr - ramziy havola o'lchamlari zarurligini aniqlaydigan bayroq. Odatiy bo'lib , u noto'g'ri , ya'ni dangasa sinf yuklash ishlatiladi. Bundan tashqari, hujjatlarga ko'ra, usulning sukut bo'yicha amalga oshirilishida qo'ng'iroq qilinadi findLoadedClass(String name)
, u sinf allaqachon yuklangan yoki yo'qligini tekshiradi va agar shunday bo'lsa, ushbu sinfga havolani qaytaradi. Aks holda, asosiy yuklovchining sinf yuklash usuli chaqiriladi. Agar yuklovchilarning hech biri yuklangan sinfni topa olmasa, ularning har biri teskari tartibda kuzatib, findClass(String name)
. Bu "Sinflarni yuklash sxemasi" bobida batafsilroq muhokama qilinadi. Va nihoyat, oxirgi, lekin eng muhimi, sinf yuklangandan so'ng, hal qilish bayrog'iga qarab , sinflarni ramziy havolalar orqali yuklash to'g'risida qaror qabul qilinadi. Aniq misol, Rezolyutsiya bosqichini sinfni yuklash bosqichida chaqirish mumkin. Shunga ko'ra, sinfni kengaytirish ClassLoader
va uning usullarini bekor qilish orqali maxsus yuklovchi virtual mashinaga bayt kodini etkazib berish uchun o'z mantiqini amalga oshirishi mumkin. Java shuningdek, "joriy" sinf yuklagichi tushunchasini qo'llab-quvvatlaydi. Joriy yuklovchi hozirda bajarilayotgan sinfni yuklagan. Har bir sinf qaysi yuklagich bilan yuklanganligini biladi va siz bu ma'lumotni uning ga qo'ng'iroq qilib olishingiz mumkin String.class.getClassLoader()
. Barcha dastur sinflari uchun "joriy" yuklovchi odatda tizim hisoblanadi.
Sinflarni yuklashning uchta printsipi
-
Delegatsiya
Sinfni yuklash so'rovi asosiy yuklovchiga uzatiladi va sinfni o'zi yuklashga urinish faqat ota-ona yuklovchi sinfni topa olmasa va yuklay olmasa amalga oshiriladi. Ushbu yondashuv sizga sinflarni asosiyga imkon qadar yaqin bo'lgan yuklagich bilan yuklash imkonini beradi. Bu sinfning maksimal ko'rinishiga erishadi. Har bir yuklovchi o'zi tomonidan yuklangan sinflarni qayd qilib, ularni keshga joylashtiradi. Ushbu sinflar to'plami qamrov deb ataladi.
-
Ko'rinish
Yuklovchi faqat "o'z" sinflarini va "ota-ona" ning sinflarini ko'radi va uning "bola" tomonidan yuklangan sinflar haqida hech qanday tasavvurga ega emas.
-
O'ziga xoslik
Sinf faqat bir marta yuklanishi mumkin. Delegatsiya mexanizmi sinfni yuklashni boshlagan yuklovchi JVM ga avval yuklangan sinfni ortiqcha yuklamasligiga ishonch hosil qiladi.
Sinfni yuklash sxemasi
Sinfni yuklash uchun qo'ng'iroq sodir bo'lganda, bu sinf joriy yuklovchining allaqachon yuklangan sinflari keshida qidiriladi. Agar kerakli sinf ilgari yuklanmagan bo'lsa, delegatsiya printsipi boshqaruvni ierarxiyada bir daraja yuqoriroq joylashgan ota-loaderga o'tkazadi. Ota yuklovchi ham keshda kerakli sinfni topishga harakat qiladi. Agar sinf allaqachon yuklangan bo'lsa va yuklovchi uning joylashgan joyini bilsa, u holdaClass
ushbu sinf ob'ekti qaytariladi. Aks holda, qidiruv asosiy yuklash moslamasiga yetguncha davom etadi. Agar asosiy yuklovchida kerakli sinf haqida ma'lumot bo'lmasa (ya'ni u hali yuklanmagan bo'lsa), bu sinfning bayt kodi yuklovchi biladigan sinflar joylashgan joyda qidiriladi va agar sinf bo'lmasa. yuklangan boʻlsa, boshqaruv unga maʼlum boʻlgan manbalardan yuklashga urinib koʻradigan bola yuklagichga qaytadi. Yuqorida aytib o'tilganidek, asosiy yuklovchi uchun sinflarning joylashuvi rt.jar kutubxonasi, kengaytmali yuklovchi uchun - jre/lib/ext kengaytmalari bo'lgan katalog, tizim uchun - CLASSPATH, foydalanuvchi uchun u boshqacha bo'lishi mumkin. . Shunday qilib, yuklash sinflarining rivojlanishi teskari yo'nalishda - ildiz yuklagichdan joriygacha boradi. Sinfning bayt-kodi topilganda, sinf JVM ga yuklanadi va turning namunasi olinadi Class
. Osonlik bilan ko'rib turganingizdek, tasvirlangan yuklash sxemasi yuqoridagi usulni amalga oshirishga o'xshaydi loadClass(String name)
. Quyida ushbu diagrammani diagrammada ko'rishingiz mumkin.
Xulosa sifatida
Tilni o'rganishning dastlabki bosqichlarida Java-da sinflar qanday yuklanishini tushunishning alohida ehtiyoji yo'q, ammo bu asosiy tamoyillarni bilish yoki kabi xatolarga duch kelganingizda umidsizlikdan qochishingizga yordamClassNotFoundException
beradi NoClassDefFoundError
. Xo'sh, yoki hech bo'lmaganda muammoning ildizi nima ekanligini tushunib oling. ClassNotFoundException
Shunday qilib, dasturni bajarish jarayonida sinf dinamik yuklanganda, yuklovchilar keshda ham, sinf yo'li bo'ylab ham kerakli sinfni topa olmasa, istisno yuzaga keladi. Ammo xato NoClassDefFoundError
yanada jiddiyroq va kerakli sinf kompilyatsiya paytida mavjud bo'lganda paydo bo'ladi, lekin dasturni bajarish paytida ko'rinmaydi. Agar dastur o'zi foydalanadigan kutubxonani qo'shishni unutgan bo'lsa, bu sodir bo'lishi mumkin. Xo'sh, o'z ishingizda foydalanadigan asbobning tuzilishi tamoyillarini tushunish haqiqati (uning chuqurligiga aniq va batafsil botirish shart emas) ushbu mexanizm ichida sodir bo'layotgan jarayonlarni tushunishga aniqlik kiritadi. o'z navbatida, ushbu vositadan ishonchli foydalanishga olib keladi.
GO TO FULL VERSION