Java ClassLoader
Java ClassLoader je apstraktna klasa. Pripada a java.lang paket. Učitava klase iz različitih izvora. Java ClassLoader koristi se za učitavanje klasa tijekom izvođenja. Drugim riječima, JVM izvodi proces povezivanja tijekom izvođenja. Klase se učitavaju u JVM prema potrebi. Ako učitana klasa ovisi o drugoj klasi, ta se klasa također učitava. Kada zatražimo učitavanje klase, ona delegira klasu svom roditelju. Na taj način se održava jedinstvenost u runtime okruženju. Neophodno je izvršiti Java program.
koliko gradova ima u Sjedinjenim Državama
Java ClassLoader temelji se na tri principa: Delegacija , Vidljivost , i Jedinstvenost .
Vrste učitavača klasa
U Javi svaki ClassLoader ima unaprijed definiranu lokaciju s koje učitava datoteke klase. Postoje sljedeće vrste ClassLoader-a u Javi:
Bootstrap učitavač klase: Učitava standardne datoteke JDK klase iz rt.jar i drugih osnovnih klasa. On je roditelj svih učitavača klase. Nema roditelja. Kada pozovemo String.class.getClassLoader(), on vraća null, a svaki kod koji se temelji na njemu izbacuje NullPointerException. Također se naziva Primordial ClassLoader. Učitava datoteke klase iz jre/lib/rt.jar. Na primjer, klasa paketa java.lang.
Učitavač klase proširenja: Delegira zahtjev za učitavanje klase svom roditelju. Ako je učitavanje klase neuspješno, učitava klase iz jre/lib/ext direktorija ili bilo kojeg drugog direktorija kao java.ext.dirs. Implementira ga sun.misc.Launcher$ExtClassLoader u JVM.
Učitavač klase sustava: Učitava klase specifične za aplikaciju iz varijable okoline CLASSPATH. Može se postaviti tijekom pokretanja programa pomoću opcija naredbenog retka -cp ili classpath. To je dijete Extension ClassLoader-a. Implementira ga klasa sun.misc.Launcher$AppClassLoader. Svi Java ClassLoader implementiraju java.lang.ClassLoader.
Kako ClassLoader radi u Javi
Kada JVM zatraži klasu, on poziva metodu loadClass() klase java.lang.ClassLoader prosljeđivanjem potpuno klasificiranog naziva klase. Metoda loadClass() poziva metodu findLoadedClass() da provjeri je li klasa već učitana ili ne. Potrebno je izbjegavati učitavanje klase više puta.
Ako je klasa već učitana, delegira zahtjev nadređenom ClassLoaderu za učitavanje klase. Ako ClassLoader ne pronalazi klasu, poziva metodu findClass() da traži klase u datotečnom sustavu. Sljedeći dijagram prikazuje kako ClassLoader učitava klasu u Javi korištenjem delegiranja.
Pretpostavimo da imamo klasu specifičnu za aplikaciju Demo.class. Zahtjev za učitavanje datoteka ove klase prenosi se u Application ClassLoader. Delegira svom nadređenom Extension ClassLoaderu. Nadalje, delegira Bootstrap ClassLoader. Bootstrap pretraži tu klasu u rt.jar i pošto te klase nema. Sada zatražite prijenos u Extension ClassLoader koji traži direktorij jre/lib/ext i tamo pokušava locirati ovu klasu. Ako je klasa tamo pronađena, Extension ClassLoader učitava tu klasu. Aplikacija ClassLoader nikada ne učitava tu klasu. Kada ga proširenje ClassLoader ne učitava, onda ga Application ClaasLoader učitava iz CLASSPATH u Javi.
Načelo vidljivosti navodi da dijete ClassLoader može vidjeti klasu koju je učitao nadređeni ClassLoader, ali obrnuto nije točno. To znači da ako Application ClassLoader učita Demo.class, u tom slučaju pokušaj učitavanja Demo.class eksplicitno koristeći Extension ClassLoader izbacuje java.lang.ClassNotFoundException.
Prema načelu jedinstvenosti, klasu koju je učitao roditelj ne bi trebao ponovno učitati Child ClassLoader. Dakle, moguće je napisati učitavač klase koji krši načela delegiranja i jedinstvenosti i sam učitava klasu.
Ukratko, učitavač klasa slijedi sljedeće pravilo:
- Provjerava je li klasa već učitana.
- Ako klasa nije učitana, zamolite učitavač klase roditelj da učita klasu.
- Ako učitavač roditeljske klase ne može učitati klasu, pokušajte je učitati u ovom učitavaču klase.
Razmotrite sljedeći primjer:
public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } }
Prevedite i pokrenite gornji kod pomoću sljedeće naredbe:
javac Demo.java java -verbose:class Demo
-verbose:class: Koristi se za prikaz informacija o klasama koje učitava JVM. Korisno je kada koristite učitavač klasa za dinamičko učitavanje klasa. Sljedeća slika prikazuje izlaz.
Možemo uočiti da se prvo učitavaju runtime klase koje zahtijeva klasa aplikacije (Demo).
Kada su klase učitane
Postoje samo dva slučaja:
- Kada se novi bajt kod izvrši.
- Kada bajt kod čini statičku referencu na klasu. Na primjer, Sustav.out .
Statičko naspram dinamičkog učitavanja klase
Klase se statički učitavaju s 'novim' operatorom. Dinamičko učitavanje klase poziva funkcije učitavača klase u vrijeme izvođenja pomoću metode Class.forName().
Razlika između loadClass() i Class.forName()
Metoda loadClass() učitava samo klasu, ali ne inicijalizira objekt. Dok metoda Class.forName() inicijalizira objekt nakon učitavanja. Na primjer, ako koristite ClassLoader.loadClass() za učitavanje JDBC upravljačkog programa, učitavač klase ne dopušta učitavanje JDBC upravljačkog programa.
Metoda java.lang.Class.forName() vraća Class Object spojen s klasom ili sučeljima s danim imenom niza. Izbacuje ClassNotFoundException ako klasa nije pronađena.
Primjer
U ovom primjeru učitava se klasa java.lang.String. Ispisuje naziv klase, naziv paketa i nazive svih dostupnih metoda klase String. Koristimo Class.forName() u sljedećem primjeru.
Klasa: Predstavlja objekt klase koji može biti bilo koje vrste (? je zamjenski znak). Vrsta klase sadrži metainformacije o klasi. Na primjer, vrsta String.class je Klasa. Koristite Class ako je klasa koja se modelira nepoznata.
getDeclaredMethod(): Vraća niz koji sadrži objekte metode koji odražavaju sve deklarirane metode klase ili sučelja koje predstavlja ovaj objekt klase, uključujući javne, zaštićene, zadani pristup (paket) i privatne metode, ali isključujući naslijeđene metode.
getName(): Vraća naziv metode predstavljen ovim Method objektom, kao String.
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(); } } }
Izlaz
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