logo

ClassLoader v jazyku Java

Java ClassLoader

Java ClassLoader je abstraktná trieda. Patrí do a java.lang balík. Načítava triedy z rôznych zdrojov. Java ClassLoader sa používa na načítanie tried za behu. Inými slovami, JVM vykonáva proces prepojenia za behu. Triedy sa načítavajú do JVM podľa potreby. Ak načítaná trieda závisí od inej triedy, načíta sa aj táto trieda. Keď požiadame o načítanie triedy, deleguje triedu svojmu rodičovi. Týmto spôsobom je zachovaná jedinečnosť v runtime prostredí. Je nevyhnutné spustiť program Java.

pothineni baran
ClassLoader v jazyku Java

Java ClassLoader je založený na troch princípoch: Delegovanie , Viditeľnosť , a Jedinečnosť .

    Princíp delegovania:Prepošle požiadavku na načítanie triedy na zavádzač rodičovskej triedy. Načíta triedu iba vtedy, ak rodič triedu nenájde alebo nenačíta.Princíp viditeľnosti:Umožňuje načítavaču podradenej triedy vidieť všetky triedy načítané nadradeným ClassLoaderom. Načítač rodičovskej triedy však nevidí triedy načítané zavádzačom podradenej triedy.Princíp jedinečnosti:Umožňuje načítať triedu raz. Dosahuje sa princípom delegovania. Zabezpečuje, že podriadený ClassLoader znovu nenačíta triedu, ktorá je už načítaná rodičom.

Typy ClassLoader

V Jave má každý ClassLoader preddefinované miesto, odkiaľ načítava súbory tried. V jazyku Java existujú nasledujúce typy ClassLoader:

Bootstrap Class Loader: Načítava štandardné súbory triedy JDK z rt.jar a iných základných tried. Je rodičom všetkých tried nakladačov. Nemá žiadneho rodiča. Keď zavoláme String.class.getClassLoader(), vráti hodnotu null a akýkoľvek kód založený na nej vyvolá výnimku NullPointerException. Nazýva sa aj Primordial ClassLoader. Načítava súbory triedy z jre/lib/rt.jar. Napríklad trieda balíka java.lang.

Načítač triedy rozšírení: Deleguje požiadavku na načítanie triedy na svojho rodiča. Ak je načítanie triedy neúspešné, načíta triedy z adresára jre/lib/ext alebo akéhokoľvek iného adresára ako java.ext.dirs. Implementuje ho sun.misc.Launcher$ExtClassLoader v JVM.

Načítač systémovej triedy: Načítava triedy špecifické pre aplikáciu z premennej prostredia CLASSPATH. Dá sa nastaviť počas spúšťania programu pomocou volieb príkazového riadku -cp alebo classpath. Je to dieťa Extension ClassLoader. Implementuje ho trieda sun.misc.Launcher$AppClassLoader. Všetky Java ClassLoader implementujú java.lang.ClassLoader.

ClassLoader v jazyku Java

Ako funguje ClassLoader v jazyku Java

Keď JVM požaduje triedu, vyvolá metódu loadClass() triedy java.lang.ClassLoader odovzdaním úplne klasifikovaného názvu triedy. Metóda loadClass() volá metódu findLoadedClass(), aby skontrolovala, či trieda už bola načítaná alebo nie. Je potrebné vyhnúť sa viacnásobnému načítaniu triedy.

Ak je trieda už načítaná, deleguje požiadavku na nadradený ClassLoader na načítanie triedy. Ak ClassLoader nenájde triedu, vyvolá metódu findClass() na vyhľadanie tried v súborovom systéme. Nasledujúci diagram ukazuje, ako ClassLoader načíta triedu v jazyku Java pomocou delegovania.

ClassLoader v jazyku Java

Predpokladajme, že máme triedu špecifickú pre aplikáciu Demo.class. Požiadavka na načítanie súborov tejto triedy sa prenesie do Application ClassLoader. Deleguje to na svoj nadradený modul Extension ClassLoader. Ďalej deleguje na Bootstrap ClassLoader. Bootstrap vyhľadajte túto triedu v rt.jar a keďže tam táto trieda nie je. Teraz požiadajte o prenos do Extension ClassLoader, ktorý vyhľadá adresár jre/lib/ext a pokúsi sa tam túto triedu nájsť. Ak sa tam trieda nájde, Extension ClassLoader načíta túto triedu. Aplikácia ClassLoader túto triedu nikdy nenačíta. Keď ho rozšírenie ClassLoader nenačíta, potom ho aplikácia ClaasLoader načíta z CLASSPATH v Jave.

Princíp viditeľnosti hovorí, že podriadený ClassLoader môže vidieť triedu načítanú rodičovským ClassLoaderom, ale naopak to neplatí. To znamená, že ak Application ClassLoader načíta Demo.class, v takom prípade pokus o načítanie Demo.class explicitne pomocou Extension ClassLoader vyvolá java.lang.ClassNotFoundException.

Podľa princípu jedinečnosti by triedu načítanú rodičom nemal znova načítať Child ClassLoader. Takže je možné napísať loader triedy, ktorý porušuje princípy delegovania a jedinečnosti a načíta triedu sám.

Stručne povedané, nakladač triedy sa riadi nasledujúcim pravidlom:

  • Skontroluje, či je trieda už načítaná.
  • Ak trieda nie je načítaná, požiadajte zavádzač rodičovskej triedy o načítanie triedy.
  • Ak zavádzač rodičovskej triedy nemôže načítať triedu, skúste ju načítať do tohto zavádzača triedy.

Zvážte nasledujúci príklad:

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

Skompilujte a spustite vyššie uvedený kód pomocou nasledujúceho príkazu:

 javac Demo.java java -verbose:class Demo 

-verbose:class: Používa sa na zobrazenie informácií o triedach, ktoré JVM načítava. Je to užitočné pri použití zavádzača tried na dynamické načítanie tried. Nasledujúci obrázok zobrazuje výstup.

ClassLoader v jazyku Java

Môžeme pozorovať, že triedy runtime vyžadované triedou aplikácie (Demo) sa načítajú ako prvé.

Keď sú triedy načítané

Existujú iba dva prípady:

  • Keď sa vykoná nový bajtový kód.
  • Keď bajtový kód vytvorí statický odkaz na triedu. Napríklad, System.out .

Statické vs. dynamické načítanie triedy

Triedy sú staticky načítané operátorom „nový“. Dynamické načítanie tried vyvolá funkcie zavádzača tried v čase spustenia pomocou metódy Class.forName().

Rozdiel medzi loadClass() a Class.forName()

Metóda loadClass() načíta iba triedu, ale neinicializuje objekt. Zatiaľ čo metóda Class.forName() inicializuje objekt po jeho načítaní. Napríklad, ak používate ClassLoader.loadClass() na načítanie ovládača JDBC, zavádzač triedy neumožňuje načítať ovládač JDBC.

Metóda java.lang.Class.forName() vráti objekt triedy spojený s triedou alebo rozhraniami s daným názvom reťazca. Vyhodí ClassNotFoundException, ak sa trieda nenájde.

Príklad

V tomto príklade je načítaná trieda java.lang.String. Vypíše názov triedy, názov balíka a názvy všetkých dostupných metód triedy String. V nasledujúcom príklade používame Class.forName().

Trieda: Predstavuje objekt triedy, ktorý môže byť akéhokoľvek typu (? je zástupný znak). Typ Class obsahuje metainformácie o triede. Napríklad typ String.class je Class. Použite Class, ak je modelovaná trieda neznáma.

getDeclaredMethod(): Vráti pole obsahujúce objekty Method odzrkadľujúce všetky deklarované metódy triedy alebo rozhrania reprezentované týmto objektom triedy, vrátane verejných, chránených, predvolených (balíkových) prístupov a súkromných metód, ale s výnimkou zdedených metód.

getName(): Vráti názov metódy reprezentovaný týmto objektom Method ako reťazec.

 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(); } } } 

Výkon

 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