logo

ClassLoader Java nyelven

Java ClassLoader

A Java ClassLoader egy absztrakt osztály. Hozzá tartozik a java.lang csomag. Különböző erőforrásokból tölti be az osztályokat. A Java ClassLoader az osztályok futási időben történő betöltésére szolgál. Más szavakkal, a JVM futás közben hajtja végre az összekapcsolási folyamatot. Az osztályokat igény szerint töltik be a JVM-be. Ha egy betöltött osztály egy másik osztálytól függ, az az osztály is betöltődik. Amikor egy osztály betöltését kérjük, az osztályt delegálja a szülőjének. Ily módon az egyediség megmarad a futási környezetben. Elengedhetetlen egy Java program futtatása.

mit jelent az xdxd
ClassLoader Java nyelven

A Java ClassLoader három alapelven alapul: Delegáció , Láthatóság , és Egyediség .

    A delegálás elve:Továbbítja az osztálybetöltési kérelmet a szülő osztálybetöltőnek. Csak akkor tölti be az osztályt, ha a szülő nem találja vagy tölti be az osztályt.A láthatóság elve:Lehetővé teszi a gyermekosztály betöltőjének, hogy lássa a szülő ClassLoader által betöltött összes osztályt. A szülő osztálybetöltő azonban nem láthatja az utódosztály-betöltő által betöltött osztályokat.Az egyediség elve:Lehetővé teszi egy osztály egyszeri betöltését. Ezt a delegálás elve éri el. Biztosítja, hogy a gyermek ClassLoader ne töltse be újra az osztályt, amelyet a szülő már betöltött.

A ClassLoader típusai

A Java-ban minden ClassLoadernek van egy előre meghatározott helye, ahonnan osztályfájlokat tölt be. Java-ban a következő típusú ClassLoader létezik:

Bootstrap osztálybetöltő: Betölti a szabványos JDK osztály fájlokat az rt.jar és más alapvető osztályokból. Az összes osztálybetöltő szülője. Nincs szülője. Amikor meghívjuk a String.class.getClassLoader() függvényt, akkor nullát ad vissza, és minden ezen alapuló kód NullPointerException-t dob. Primordial ClassLoadernek is nevezik. Osztályfájlokat tölt be a jre/lib/rt.jar-ból. Például java.lang csomagosztály.

Bővítmények osztálybetöltő: Delegálja az osztálybetöltési kérelmet a szülőjének. Ha egy osztály betöltése sikertelen, az osztályokat a jre/lib/ext könyvtárból vagy bármely más könyvtárból tölti be java.ext.dirs néven. A JVM-ben a sun.misc.Launcher$ExtClassLoader valósítja meg.

Rendszerosztály betöltő: Az alkalmazásspecifikus osztályokat a CLASSPATH környezeti változóból tölti be. Beállítható a program meghívásakor a -cp vagy classpath parancssori paraméterekkel. Ez az Extension ClassLoader gyermeke. A sun.misc.Launcher$AppClassLoader osztály valósítja meg. Az összes Java ClassLoader megvalósítja a java.lang.ClassLoader-t.

ClassLoader Java nyelven

Hogyan működik a ClassLoader a Java-ban

Amikor a JVM egy osztályt kér, meghívja a java.lang.ClassLoader osztály loadClass() metódusát az osztály teljesen besorolt ​​nevének átadásával. A loadClass() metódus meghívja a findLoadedClass() metódust annak ellenőrzésére, hogy az osztály már be van-e töltve vagy sem. El kell kerülni az osztály többszöri betöltését.

Ha az osztály már be van töltve, akkor átadja a kérést a szülő ClassLoadernek az osztály betöltésére. Ha a ClassLoader nem találja az osztályt, akkor meghívja a findClass() metódust, hogy megkeresse az osztályokat a fájlrendszerben. A következő diagram azt mutatja be, hogy a ClassLoader hogyan tölti be az osztályt Java nyelven delegálás segítségével.

ClassLoader Java nyelven

Tegyük fel, hogy van egy alkalmazásspecifikus osztályunk Demo.class. Az osztályfájlok betöltésére vonatkozó kérés átkerül az Application ClassLoaderbe. Delegálja a szülő bővítmény ClassLoader-re. Továbbá átadja a Bootstrap ClassLoadernek. A Bootstrap megkeresi azt az osztályt az rt.jar fájlban, és mivel az osztály nincs ott. Most kérje az átvitelt az Extension ClassLoaderhez, amely megkeresi a jre/lib/ext könyvtárat, és megpróbálja ott megtalálni ezt az osztályt. Ha az osztály ott található, az Extension ClassLoader betölti az osztályt. Az Application ClassLoader soha nem tölti be ezt az osztályt. Ha a ClassLoader kiterjesztés nem tölti be, akkor az Application ClaasLoader a Java CLASSPATH-ból tölti be.

A láthatósági elv szerint a gyermek ClassLoader láthatja a szülő ClassLoader által betöltött osztályt, de fordítva nem igaz. Ez azt jelenti, hogy ha az Application ClassLoader betölti a Demo.class-t, ebben az esetben a Demo.class Extension ClassLoader használatával történő explicit betöltése a java.lang.ClassNotFoundException fájlt dobja.

Az egyediség elve szerint a szülő által betöltött osztályt a Child ClassLoader nem töltheti be újra. Tehát lehetséges olyan osztálybetöltőt írni, amely megsérti a delegálás és az egyediség elveit, és önmagában tölti be az osztályt.

Röviden, az osztálybetöltő a következő szabályt követi:

  • Ellenőrzi, hogy az osztály már betöltődött-e.
  • Ha az osztály nincs betöltve, kérje meg a szülő osztálybetöltőt, hogy töltse be az osztályt.
  • Ha a szülő osztálybetöltő nem tudja betölteni az osztályt, próbálja meg betölteni ebben az osztálybetöltőben.

Tekintsük a következő példát:

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

Fordítsa le és futtassa a fenti kódot a következő paranccsal:

 javac Demo.java java -verbose:class Demo 

-verbose:class: A JVM által betöltött osztályokkal kapcsolatos információk megjelenítésére szolgál. Hasznos, ha osztálybetöltőt használunk az osztályok dinamikus betöltésére. A következő ábra a kimenetet mutatja.

ClassLoader Java nyelven

Megfigyelhetjük, hogy az alkalmazásosztály (Demo) által igényelt futásidejű osztályok töltődnek be először.

Amikor betöltődnek az osztályok

Csak két eset van:

  • Amikor az új bájtkód végrehajtásra kerül.
  • Amikor a bájtkód statikus hivatkozást tesz egy osztályra. Például, System.out .

Statikus vs. dinamikus osztálybetöltés

Az osztályok statikusan betöltődnek az „új” operátorral. A dinamikus osztálybetöltés a Class.forName() metódussal futás közben meghívja az osztálybetöltő funkcióit.

A loadClass() és a Class.forName() közötti különbség

A loadClass() metódus csak az osztályt tölti be, de nem inicializálja az objektumot. Míg a Class.forName() metódus inicializálja az objektumot a betöltése után. Például, ha a ClassLoader.loadClass() függvényt használja a JDBC illesztőprogram betöltéséhez, az osztálybetöltő nem teszi lehetővé a JDBC illesztőprogram betöltését.

A java.lang.Class.forName() metódus visszaadja az osztályobjektumot az adott karakterláncnévvel rendelkező osztályhoz vagy interfészekhez társítva. ClassNotFoundException kivételt dob, ha az osztály nem található.

Példa

Ebben a példában a java.lang.String osztály van betöltve. Kiírja az osztály nevét, a csomag nevét és a String osztály összes elérhető metódusának nevét. A következő példában a Class.forName() függvényt használjuk.

Osztály: Osztály objektumot jelöl, amely bármilyen típusú lehet (? helyettesítő karakter). Az Osztály típus metainformációkat tartalmaz egy osztályról. Például a String.class típusa Class. Használja az Osztályt, ha a modellezett osztály ismeretlen.

getDeclaredMethod(): Egy Method objektumokat tartalmazó tömböt ad vissza, amely tükrözi az osztály objektum által képviselt osztály vagy interfész összes deklarált metódusát, beleértve a nyilvános, védett, alapértelmezett (csomag) hozzáférést és privát metódusokat, de nem tartalmazza az örökölt metódusokat.

getName(): A Method objektum által képviselt metódusnevet karakterláncként adja vissza.

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

Kimenet

 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