logo

ClassLoader v Javi

Java ClassLoader

Java ClassLoader je abstrakten razred. Pripada a java.lang paket. Nalaga razrede iz različnih virov. Java ClassLoader se uporablja za nalaganje razredov med izvajanjem. Z drugimi besedami, JVM izvede postopek povezovanja med izvajanjem. Razredi se po potrebi naložijo v JVM. Če je naložen razred odvisen od drugega razreda, se naloži tudi ta razred. Ko zahtevamo nalaganje razreda, ga delegira svojemu nadrejenemu. Na ta način se ohrani edinstvenost v izvajalnem okolju. Bistvenega pomena je izvajanje programa Java.

python shrani json v datoteko
ClassLoader v Javi

Java ClassLoader temelji na treh načelih: Delegacija , Vidnost , in Edinstvenost .

    Načelo delegiranja:Zahtevo za nalaganje razreda posreduje nalagalniku nadrejenega razreda. Razred naloži le, če nadrejeni razred ne najde ali naloži.Načelo vidnosti:Nalagalniku podrejenih razredov omogoča ogled vseh razredov, ki jih je naložil nadrejeni ClassLoader. Toda nalagalnik nadrejenega razreda ne more videti razredov, ki jih je naložil nalagalnik podrejenega razreda.Načelo edinstvenosti:Omogoča enkratno nalaganje razreda. Doseže se po principu delegiranja. Zagotavlja, da podrejeni ClassLoader ne naloži znova razreda, ki ga je že naložil nadrejeni.

Vrste nalagalnika razredov

V Javi ima vsak ClassLoader vnaprej določeno lokacijo, od koder nalaga datoteke razreda. V Javi obstajajo naslednje vrste ClassLoader:

Nalagalnik razredov Bootstrap: Naloži standardne datoteke razreda JDK iz rt.jar in drugih osnovnih razredov. Je nadrejeni za vse nalagalnike razredov. Nima nobenega starša. Ko pokličemo String.class.getClassLoader(), vrne vrednost null in katera koli koda, ki temelji na njej, vrže NullPointerException. Imenuje se tudi Primordial ClassLoader. Naloži datoteke razreda iz jre/lib/rt.jar. Na primer razred paketa java.lang.

Nalagalnik razredov razširitev: Zahtevo za nalaganje razreda prenese na svojega nadrejenega. Če je nalaganje razreda neuspešno, naloži razrede iz imenika jre/lib/ext ali katerega koli drugega imenika kot java.ext.dirs. Izvaja ga sun.misc.Launcher$ExtClassLoader v JVM.

Nalagalnik sistemskih razredov: Naloži razrede, specifične za aplikacijo, iz spremenljivke okolja CLASSPATH. Nastavite ga lahko med priklicem programa z možnostmi ukazne vrstice -cp ali classpath. Je podrejeni element Extension ClassLoader. Izvaja ga razred sun.misc.Launcher$AppClassLoader. Vsi Java ClassLoader implementirajo java.lang.ClassLoader.

ClassLoader v Javi

Kako ClassLoader deluje v Javi

Ko JVM zahteva razred, prikliče metodo loadClass() razreda java.lang.ClassLoader tako, da posreduje popolnoma razvrščeno ime razreda. Metoda loadClass() pokliče metodo findLoadedClass(), da preveri, ali je razred že naložen ali ne. Izogibati se je treba večkratnemu nalaganju razreda.

Če je razred že naložen, delegira zahtevo nadrejenemu ClassLoaderju, da naloži razred. Če ClassLoader ne najde razreda, pokliče metodo findClass(), da poišče razrede v datotečnem sistemu. Naslednji diagram prikazuje, kako ClassLoader naloži razred v Javi z delegiranjem.

ClassLoader v Javi

Recimo, da imamo razred Demo.class, specifičen za aplikacijo. Zahteva za nalaganje datotek tega razreda se prenese v Application ClassLoader. Delegira svojemu nadrejenemu Extension ClassLoader. Nadalje delegira na Bootstrap ClassLoader. Bootstrap poišče ta razred v rt.jar in ker tega razreda ni. Zdaj zahtevajte prenos v Extension ClassLoader, ki išče imenik jre/lib/ext in tam poskuša poiskati ta razred. Če je razred tam najden, Extension ClassLoader naloži ta razred. Aplikacija ClassLoader nikoli ne naloži tega razreda. Če je razširitev ClassLoader ne naloži, jo aplikacija ClaasLoader naloži iz CLASSPATH v Javi.

Načelo vidnosti navaja, da lahko podrejeni ClassLoader vidi razred, ki ga je naložil nadrejeni ClassLoader, vendar obratno ne drži. To pomeni, da če Application ClassLoader naloži Demo.class, v takem primeru poskus nalaganja Demo.class izrecno z uporabo Extension ClassLoader vrže java.lang.ClassNotFoundException.

V skladu z načelom edinstvenosti razreda, ki ga je naložil nadrejeni razred, Child ClassLoader ne sme znova naložiti. Torej je mogoče napisati nalagalnik razreda, ki krši načela delegiranja in edinstvenosti ter sam naloži razred.

Skratka, nalagalnik razredov sledi naslednjemu pravilu:

  • Preveri, ali je razred že naložen.
  • Če razred ni naložen, prosite nadrejeni nalagalnik razreda, da naloži razred.
  • Če nalagalnik nadrejenega razreda ne more naložiti razreda, ga poskusite naložiti v tem nalagalniku razredov.

Razmislite o naslednjem primeru:

 public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } } 

Z naslednjim ukazom prevedite in zaženite zgornjo kodo:

 javac Demo.java java -verbose:class Demo 

-podrobno:razred: Uporablja se za prikaz informacij o razredih, ki jih nalaga JVM. Uporaben je pri uporabi nalagalnika razredov za dinamično nalaganje razredov. Naslednja slika prikazuje izhod.

ClassLoader v Javi

Opazimo lahko, da se najprej naložijo izvajalni razredi, ki jih zahteva razred aplikacije (Demo).

Ko so razredi naloženi

Obstajata samo dva primera:

  • Ko se izvede nova bajtna koda.
  • Ko se bajtna koda statično sklicuje na razred. na primer System.out .

Statično proti dinamičnemu nalaganju razreda

Razredi so statično naloženi z 'new' operatorjem. Dinamično nalaganje razreda prikliče funkcije nalagalnika razredov v času izvajanja z uporabo metode Class.forName().

Razlika med loadClass() in Class.forName()

Metoda loadClass() naloži samo razred, ne inicializira pa objekta. Medtem ko metoda Class.forName() inicializira predmet po nalaganju. Na primer, če uporabljate ClassLoader.loadClass() za nalaganje gonilnika JDBC, nalagalnik razredov ne dovoljuje nalaganja gonilnika JDBC.

Metoda java.lang.Class.forName() vrne predmet razreda, povezan z razredom ali vmesniki z danim imenom niza. Vrže ClassNotFoundException, če razreda ni mogoče najti.

Primer

V tem primeru je naložen razred java.lang.String. Natisne ime razreda, ime paketa in imena vseh razpoložljivih metod razreda String. V naslednjem primeru uporabljamo Class.forName().

Razred: Predstavlja predmet razreda, ki je lahko katere koli vrste (? je nadomestni znak). Vrsta razreda vsebuje metainformacije o razredu. Na primer, vrsta String.class je Razred. Uporabite razred, če modelirani razred ni znan.

getDeclaredMethod(): Vrne matriko, ki vsebuje objekte metode, ki odražajo vse deklarirane metode razreda ali vmesnika, ki ga predstavlja ta predmet razreda, vključno z javnimi, zaščitenimi, privzetimi (paketnimi) dostopnimi in zasebnimi metodami, vendar brez podedovanih metod.

getName(): Vrne ime metode, ki ga predstavlja ta objekt metode, kot niz.

 import java.lang.reflect.Method; public class ClassForNameExample { public static void main(String[] args) { try { Class cls = Class.forName('java.lang.String'); System.out.println('Class Name: ' + cls.getName()); System.out.println('Package Name: ' + cls.getPackage()); Method[] methods = cls.getDeclaredMethods(); System.out.println('-----Methods of String class -------------'); for (Method method : methods) { System.out.println(method.getName()); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } 

Izhod

 Class Name: java.lang.String Package Name: package java.lang -----Methods of String class ------------- value coder equals length toString hashCode getChars ------ ------ ------ intern isLatin1 checkOffset checkBoundsOffCount checkBoundsBeginEnd access0 access0