Sinif yükləyicisi
O, tərtib edilmiş bayt kodunu JVM-ə çatdırmaq üçün istifadə olunur, adətən uzantısı olan fayllarda saxlanılır.class
, lakin digər mənbələrdən də əldə edilə bilər, məsələn, şəbəkə üzərindən yüklənmiş və ya proqramın özü tərəfindən yaradıla bilər. Java SE spesifikasiyasına uyğun olaraq, JVM-də kodu işə salmaq üçün üç addımı tamamlamalısınız:
-
resurslardan bayt kodunu yükləmək və sinfin nümunəsini yaratmaq
Class
Buraya əvvəllər yüklənmişlər arasında tələb olunan sinfin axtarışı, yükləmək üçün bayt kodunun əldə edilməsi və onun düzgünlüyünün yoxlanılması, sinfin nümunəsinin yaradılması
Class
(iş vaxtında onunla işləmək üçün) və ana siniflərin yüklənməsi daxildir. Əgər ana siniflər və interfeyslər yüklənməyibsə, o zaman sözügedən sinif yüklənməmiş hesab olunur. -
bağlama (və ya bağlama)
Spesifikasiyaya görə, bu mərhələ daha üç mərhələyə bölünür:
- Doğrulama , alınan bayt kodunun düzgünlüyü yoxlanılır.
- Hazırlıq , RAM-ın statik sahələr üçün ayrılması və onların standart dəyərlərlə işə salınması (bu halda, əgər varsa, açıq başlatma artıq başlanğıc mərhələsində baş verir).
- Rezolyutsiya , növlərin, sahələrin və metodların simvolik əlaqələrinin həlli.
-
qəbul edilmiş obyektin işə salınması
burada, əvvəlki bəndlərdən fərqli olaraq, nə baş verməli, hər şey aydın görünür. Bunun necə baş verdiyini anlamaq, əlbəttə ki, maraqlı olardı.
- Əlaqələndirmədən əvvəl sinif tam yüklənməlidir.
- Sinif işə salınmazdan əvvəl tam sınaqdan keçirilməli və hazırlanmalıdır.
- Bağlantının həlli xətaları, hətta əlaqələndirmə mərhələsində aşkar edilsə belə, proqramın icrası zamanı baş verir.
Java yükləyicilərinin növləri
Java-da üç standart yükləyici var, onların hər biri müəyyən bir yerdən bir sinif yükləyir:-
Bootstrap , Primordial ClassLoader adlanan əsas yükləyicidir.
rt.jar arxivindən standart JDK siniflərini yükləyir
-
Extension ClassLoader – genişləndirici yükləyici.
defolt olaraq jre/lib/ext qovluğunda yerləşən, lakin java.ext.dirs sistem xassəsi ilə təyin edilə bilən genişləndirmə siniflərini yükləyir.
-
System ClassLoader – sistem yükləyicisi.
CLASSPATH mühit dəyişənində müəyyən edilmiş tətbiq siniflərini yükləyir
Abstrakt sinif ClassLoader
Əsas yükləyici istisna olmaqla, hər bir yükləyici mücərrəd sinifin nəslindəndirjava.lang.ClassLoader
. Məsələn, genişləndirici yükləyicinin tətbiqi sinifdir sun.misc.Launcher$ExtClassLoader
, sistem yükləyicisi isə sun.misc.Launcher$AppClassLoader
. Əsas yükləyici yerlidir və onun tətbiqi JVM-ə daxildir. Genişlənən hər hansı bir sinif, java.lang.ClassLoader
blackjack və eyni olanlarla dərsləri yükləmək üçün öz yolunu təmin edə bilər. Bunun üçün müvafiq metodları yenidən müəyyən etmək lazımdır, bu anda mən yalnız səthi hesab edə bilərəm, çünki Bu məsələni ətraflı başa düşmədim. Budur onlar:
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)
dərsləri yükləmək üçün giriş nöqtəsi olan bir neçə ictimai metoddan biridir. loadClass(String name, boolean resolve)
Onun həyata keçirilməsi , ləğv edilməli olan başqa qorunan metodun çağırılması ilə nəticələnir . Bu qorunan metodun Javadoc-a baxsanız, aşağıdakı kimi bir şey başa düşə bilərsiniz: iki parametr giriş kimi verilir. Bunlardan biri yüklənməli olan sinfin binar adıdır (və ya tam uyğunlaşdırılmış sinif adı). Sinif adı bütün paketlərin siyahısı ilə müəyyən edilir. İkinci parametr simvolik keçid həllinin tələb olunub-olunmamasını müəyyən edən bayraqdır. Varsayılan olaraq false , yəni tənbəl sinif yükləməsindən istifadə olunur. Bundan əlavə, sənədlərə görə, metodun standart tətbiqində, findLoadedClass(String name)
sinfin əvvəllər yüklənib-yüklənilmədiyini yoxlayan və əgər varsa, bu sinfə istinad qaytaran bir zəng edilir. Əks halda, ana yükləyicinin sinif yükləmə metodu çağırılacaq. Əgər yükləyicilərdən heç biri yüklənmiş sinfi tapa bilməsə, onların hər biri tərs ardıcıllıqla izləyərək, findClass(String name)
. Bu, “Sinif yükləmə sxemi” fəslində daha ətraflı müzakirə olunacaq. Və nəhayət, sonuncu, lakin ən azı, sinif yükləndikdən sonra, həll bayrağından asılı olaraq , simvolik keçidlər vasitəsilə siniflərin yüklənib-yüklənməyəcəyinə qərar veriləcək. Aydın bir nümunə, Rezolyutsiya mərhələsini sinif yükləmə mərhələsində çağırmaq olar. Müvafiq olaraq, sinfi genişləndirməklə ClassLoader
və onun üsullarını ləğv etməklə, fərdi yükləyici virtual maşına bayt kodu çatdırmaq üçün öz məntiqini həyata keçirə bilər. Java həmçinin "cari" sinif yükləyicisi konsepsiyasını dəstəkləyir. Cari yükləyici hazırda icra olunan sinfi yükləyəndir. Hər bir sinif hansı yükləyici ilə yükləndiyini bilir və siz bu məlumatı onun nömrəsinə zəng etməklə əldə edə bilərsiniz String.class.getClassLoader()
. Bütün tətbiq sinifləri üçün "cari" yükləyici adətən sistemdir.
Sinif yüklənməsinin üç prinsipi
-
Nümayəndə heyəti
Sinfin yüklənməsi sorğusu ana yükləyiciyə ötürülür və sinfin özünü yükləmək cəhdi yalnız ana yükləyici sinfi tapıb yükləyə bilmədikdə edilir. Bu yanaşma sinifləri bazaya mümkün qədər yaxın olan yükləyici ilə yükləməyə imkan verir. Bu, maksimum sinif görmə qabiliyyətinə nail olur. Hər bir yükləyici onun yüklədiyi siniflərin qeydini saxlayır və onları öz keşinə yerləşdirir. Bu siniflərin çoxluğuna əhatə dairəsi deyilir.
-
Görünüş
Yükləyici yalnız "öz" siniflərini və "valideyn"in siniflərini görür və "uşaq" tərəfindən yüklənmiş siniflər haqqında heç bir fikri yoxdur.
-
Unikallıq
Bir sinif yalnız bir dəfə yüklənə bilər. Nümayəndə heyəti mexanizmi sinif yükləməsini başlatan yükləyicinin əvvəllər JVM-ə yüklənmiş sinfi həddindən artıq yükləmədiyinə əmin olur.
Sinif yükləmə sxemi
Bir sinfi yükləmək üçün zəng baş verdikdə, bu sinif cari yükləyicinin artıq yüklənmiş siniflərinin keşində axtarılır. İstədiyiniz sinif əvvəllər yüklənməyibsə, delegasiya prinsipi nəzarəti iyerarxiyada bir səviyyə yuxarıda yerləşən ana yükləyiciyə ötürür. Ana yükləyici də öz keşində istədiyiniz sinfi tapmağa çalışır. Əgər sinif artıq yüklənibsə və yükləyici onun yerini bilirsə, o zamanClass
həmin sinfin obyekti qaytarılacaq. Əks halda, axtarış əsas yükləyiciyə çatana qədər davam edəcək. Baza yükləyicinin tələb olunan sinif haqqında məlumatı yoxdursa (yəni hələ yüklənməyib), bu sinfin bayt kodu verilmiş yükləyicinin bildiyi siniflərin yerində axtarılacaq və əgər sinif bunu edə bilmirsə. yükləndikdə, idarəetmə ona məlum olan mənbələrdən yükləməyə çalışacaq uşaq yükləyiciyə qayıdacaq. Yuxarıda qeyd edildiyi kimi, əsas yükləyici üçün siniflərin yeri rt.jar kitabxanasıdır, genişləndirici yükləyici üçün - jre/lib/ext uzantıları olan kataloq, sistem üçün - CLASSPATH, istifadəçi üçün fərqli bir şey ola bilər. . Beləliklə, yükləmə siniflərinin tərəqqisi əks istiqamətdə - kök yükləyicidən cari birinə doğru gedir. Sinfin bayt kodu tapıldıqda, sinif JVM-ə yüklənir və növün nümunəsi əldə edilir Class
. Asanlıqla gördüyünüz kimi, təsvir edilən yükləmə sxemi yuxarıda göstərilən metodun həyata keçirilməsinə bənzəyir loadClass(String name)
. Aşağıda bu diaqramı diaqramda görə bilərsiniz.
Nəticə olaraq
Dil öyrənməyin ilk addımlarında Java-da dərslərin necə yükləndiyini anlamağa xüsusi ehtiyac yoxdur, lakin bu əsas prinsipləri bilmək və ya kimi səhvlərlə qarşılaşdığınız zaman ümidsizliyə qapılmağınıza köməkClassNotFoundException
edəcək NoClassDefFoundError
. Yaxşı, ya da heç olmasa problemin kökünün nə olduğunu anlayın. ClassNotFoundException
Beləliklə, proqramın icrası zamanı sinif dinamik şəkildə yükləndikdə, yükləyicilər tələb olunan sinfi nə keşdə, nə də sinif yolu boyunca tapa bilmədikdə, istisna baş verir. Lakin səhv NoClassDefFoundError
daha kritikdir və tələb olunan sinif tərtib zamanı mövcud olduqda, lakin proqramın icrası zamanı görünmədikdə baş verir. Bu, proqram istifadə etdiyi kitabxananı daxil etməyi unutduqda baş verə bilər. Yaxşı, işinizdə istifadə etdiyiniz alətin strukturunun prinsiplərini başa düşmək faktının özü (mütləq onun dərinliklərinə aydın və müfəssəl daldırma deyil) bu mexanizmin daxilində baş verən proseslərin başa düşülməsinə müəyyən aydınlıq əlavə edir. öz növbəsində, bu alətdən inamlı istifadəyə səbəb olur.
GO TO FULL VERSION