Java ClassLoader
Java ClassLoader on abstrakti luokka. Se kuuluu a java.lang paketti. Se lataa luokat eri resursseista. Java ClassLoader -ohjelmaa käytetään luokkien lataamiseen ajon aikana. Toisin sanoen JVM suorittaa linkitysprosessin ajon aikana. Luokat ladataan JVM:ään tarpeen mukaan. Jos ladattu luokka riippuu toisesta luokasta, myös tämä luokka ladataan. Kun pyydämme luokan lataamista, se delegoi luokan vanhemmalleen. Näin ainutlaatuisuus säilyy ajonaikaisessa ympäristössä. Java-ohjelman suorittaminen on välttämätöntä.
mikä on uri
Java ClassLoader perustuu kolmeen periaatteeseen: valtuuskunta , Näkyvyys , ja Ainutlaatuisuus .
Classloader-tyypit
Javassa jokaisella ClassLoaderilla on ennalta määritetty sijainti, josta ne lataavat luokkatiedostoja. Javassa on seuraavan tyyppisiä ClassLoader-tiedostoja:
Bootstrap Class Loader: Se lataa tavallisia JDK-luokkatiedostoja rt.jar-tiedostosta ja muista ydinluokista. Se on kaikkien luokkakuormaajien vanhempi. Sillä ei ole vanhempia. Kun kutsumme String.class.getClassLoader():tä, se palauttaa nullin, ja mikä tahansa siihen perustuva koodi heittää NullPointerExceptionin. Sitä kutsutaan myös nimellä Primordial ClassLoader. Se lataa luokkatiedostot tiedostosta jre/lib/rt.jar. Esimerkiksi java.lang-pakettiluokka.
Laajennusten luokan latausohjelma: Se delegoi luokan latauspyynnön vanhemmalleen. Jos luokan lataus epäonnistuu, se lataa luokat jre/lib/ext-hakemistosta tai mistä tahansa muusta hakemistosta nimellä java.ext.dirs. Sen toteuttaa sun.misc.Launcher$ExtClassLoader JVM:ssä.
Järjestelmäluokan latausohjelma: Se lataa sovelluskohtaiset luokat CLASSPATH-ympäristömuuttujasta. Se voidaan asettaa kutsuttaessa ohjelmaa käyttämällä -cp- tai classpath-komentorivin valintoja. Se on Extension ClassLoaderin lapsi. Sen toteuttaa sun.misc.Launcher$AppClassLoader-luokka. Kaikki Java ClassLoader toteuttaa java.lang.ClassLoader.
Miten ClassLoader toimii Javassa
Kun JVM pyytää luokkaa, se kutsuu java.lang.ClassLoader-luokan loadClass()-metodin välittämällä luokan täysin luokitellun nimen. loadClass()-metodi pyytää findLoadedClass()-menetelmää tarkistamaan, onko luokka jo ladattu vai ei. On vältettävä luokan lataamista useaan kertaan.
Jos luokka on jo ladattu, se siirtää pyynnön luokan lataamista varten ClassLoaderille. Jos ClassLoader ei löydä luokkaa, se pyytää findClass()-metodia etsimään luokat tiedostojärjestelmästä. Seuraava kaavio näyttää, kuinka ClassLoader lataa luokan Javassa delegoinnin avulla.
Oletetaan, että meillä on sovelluskohtainen luokka Demo.class. Tämän luokan tiedostojen latauspyyntö siirtyy Application ClassLoaderille. Se delegoi sen ylätason Extension ClassLoaderille. Lisäksi se delegoituu Bootstrap ClassLoaderille. Bootstrap etsi kyseistä luokkaa tiedostosta rt.jar ja koska sitä luokkaa ei ole siellä. Pyydä nyt siirtoa Extension ClassLoaderille, joka etsii hakemistoa jre/lib/ext ja yrittää paikantaa tämän luokan sieltä. Jos luokka löytyy sieltä, Extension ClassLoader lataa kyseisen luokan. Application ClassLoader ei koskaan lataa kyseistä luokkaa. Kun ClassLoader-laajennus ei lataa sitä, sovellus ClaasLoader lataa sen Javan CLASSPATHista.
Näkyvyysperiaate sanoo, että alatason ClassLoader voi nähdä ylätason ClassLoaderin lataaman luokan, mutta päinvastoin ei pidä paikkaansa. Se tarkoittaa, että jos Application ClassLoader lataa Demo.classin, siinä tapauksessa, että Demo.classin lataaminen eksplisiittisesti Extension ClassLoaderin avulla heittää java.lang.ClassNotFoundExceptionin.
Ainutlaatuisuusperiaatteen mukaan Child ClassLoader ei saa ladata ylätason lataamaa luokkaa uudelleen. Joten on mahdollista kirjoittaa luokkalataaja, joka rikkoo delegointi- ja ainutlaatuisuusperiaatteita ja lataa luokan itsestään.
Lyhyesti sanottuna luokan latausohjelma noudattaa seuraavaa sääntöä:
- Se tarkistaa, onko luokka jo ladattu.
- Jos luokkaa ei ladata, pyydä vanhempien luokan latausohjelmaa lataamaan luokka.
- Jos yläluokan latausohjelma ei voi ladata luokkaa, yritä ladata se tässä luokan latausohjelmassa.
Harkitse seuraavaa esimerkkiä:
public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } }
Käännä ja suorita yllä oleva koodi käyttämällä seuraavaa komentoa:
javac Demo.java java -verbose:class Demo
-verbose:class: Sitä käytetään näyttämään tiedot JVM:n lataamista luokista. Se on hyödyllinen käytettäessä luokkalataajaa luokkien dynaamiseen lataamiseen. Seuraava kuva näyttää ulostulon.
Voimme havaita, että sovellusluokan (Demo) vaatimat ajonaikaiset luokat ladataan ensin.
Kun luokat ladataan
Tapauksia on vain kaksi:
- Kun uusi tavukoodi suoritetaan.
- Kun tavukoodi viittaa staattiseen luokkaan. Esimerkiksi, System.out .
Staattinen vs. dynaaminen luokan lataus
Luokat ladataan staattisesti 'uudella' operaattorilla. Dynaaminen luokkalataus kutsuu luokkalataimen toimintoja ajon aikana käyttämällä Class.forName() -metodia.
Ero loadClass():n ja Class.forName() välillä
loadClass()-metodi lataa vain luokan, mutta ei alusta objektia. Vaikka Class.forName() -menetelmä alustaa objektin sen lataamisen jälkeen. Jos esimerkiksi käytät ClassLoader.loadClass()-komentoa JDBC-ohjaimen lataamiseen, luokan latausohjelma ei salli JDBC-ohjaimen lataamista.
Metodi java.lang.Class.forName() palauttaa luokkaobjektin yhdistettynä luokkaan tai liitäntöihin, joilla on annettu merkkijononimi. Se heittää ClassNotFoundExceptionin, jos luokkaa ei löydy.
Esimerkki
Tässä esimerkissä java.lang.String-luokka ladataan. Se tulostaa luokan nimen, paketin nimen ja kaikkien String-luokan käytettävissä olevien menetelmien nimet. Käytämme Class.forName():ta seuraavassa esimerkissä.
Luokka: Edustaa luokkaobjektia, joka voi olla mitä tahansa tyyppiä (? on jokerimerkki). Luokka-tyyppi sisältää metatietoja luokasta. Esimerkiksi String.class-tyyppi on Class. Käytä Luokkaa, jos mallinnettava luokka on tuntematon.
getDeclaredMethod(): Palauttaa taulukon, joka sisältää Method-objekteja, jotka heijastavat kaikkia tämän luokkaobjektin edustaman luokan tai liitännän ilmoitettuja menetelmiä, mukaan lukien julkiset, suojatut, oletuskäyttö (paketti) ja yksityiset menetelmät, mutta ei perittyjä menetelmiä.
getName(): Se palauttaa tämän Method-objektin edustaman menetelmän nimen merkkijonona.
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(); } } }
Lähtö
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