Java ClassLoader
Java ClassLoader er en abstrakt klasse. Den tilhører en java.lang pakke. Den laster klasser fra forskjellige ressurser. Java ClassLoader brukes til å laste klassene under kjøretid. Med andre ord, JVM utfører koblingsprosessen under kjøring. Klasser lastes inn i JVM etter behov. Hvis en lastet klasse avhenger av en annen klasse, lastes den klassen også. Når vi ber om å laste inn en klasse, delegerer den klassen til den overordnede. På denne måten opprettholdes unikhet i kjøretidsmiljøet. Det er viktig å kjøre et Java-program.
nettsted som coomeet
Java ClassLoader er basert på tre prinsipper: Delegasjon , Synlighet , og Unikhet .
Typer ClassLoader
I Java har hver ClassLoader en forhåndsdefinert plassering hvorfra de laster klassefiler. Det finnes følgende typer ClassLoader i Java:
Bootstrap Class Loader: Den laster standard JDK-klassefiler fra rt.jar og andre kjerneklasser. Det er en forelder til alle klasselastere. Den har ingen foreldre. Når vi kaller String.class.getClassLoader() returnerer den null, og all kode basert på den kaster NullPointerException. Det kalles også Primordial ClassLoader. Den laster klassefiler fra jre/lib/rt.jar. For eksempel java.lang-pakkeklassen.
Klasselaster for utvidelser: Den delegerer forespørsel om klasseinnlasting til forelderen. Hvis lasting av en klasse ikke lykkes, laster den inn klasser fra jre/lib/ext-katalogen eller en hvilken som helst annen katalog som java.ext.dirs. Den er implementert av sun.misc.Launcher$ExtClassLoader i JVM.
Systemklasselaster: Den laster inn applikasjonsspesifikke klasser fra miljøvariabelen CLASSPATH. Det kan settes mens du starter programmet ved å bruke -cp eller classpath kommandolinjealternativer. Det er et barn av Extension ClassLoader. Den er implementert av sun.misc.Launcher$AppClassLoader-klassen. Alle Java ClassLoader implementerer java.lang.ClassLoader.
Hvordan ClassLoader fungerer i Java
Når JVM ber om en klasse, påkaller den en loadClass()-metode for java.lang.ClassLoader-klassen ved å sende det fullstendig klassifiserte navnet på klassen. loadClass()-metoden kaller for findLoadedClass()-metoden for å sjekke at klassen allerede er lastet eller ikke. Det kreves for å unngå å laste klassen flere ganger.
Hvis klassen allerede er lastet, delegerer den forespørselen til overordnet ClassLoader om å laste klassen. Hvis ClassLoader ikke finner klassen, starter den findClass()-metoden for å se etter klassene i filsystemet. Følgende diagram viser hvordan ClassLoader laster klasse i Java ved hjelp av delegering.
Anta at vi har en applikasjonsspesifikk klasse Demo.class. Forespørselen om lasting av denne klassefilene overføres til Application ClassLoader. Den delegerer til sin overordnede Extension ClassLoader. Videre delegeres det til Bootstrap ClassLoader. Bootstrap søk den klassen i rt.jar og siden den klassen ikke er der. Be nå om overføring til Extension ClassLoader som søker etter katalogen jre/lib/ext og prøver å finne denne klassen der. Hvis klassen finnes der, laster Extension ClassLoader den klassen. Application ClassLoader laster aldri den klassen. Når utvidelsen ClassLoader ikke laster den, laster Application ClaasLoader den fra CLASSPATH i Java.
Synlighetsprinsippet sier at underordnet ClassLoader kan se klassen lastet av den overordnede ClassLoader, men omvendt er ikke sant. Det betyr at hvis Application ClassLoader laster Demo.class, i slike tilfeller, prøver å laste Demo.class eksplisitt ved å bruke Extension ClassLoader kaster java.lang.ClassNotFoundException.
I henhold til unikhetsprinsippet skal en klasse lastet av forelderen ikke lastes av Child ClassLoader igjen. Så det er mulig å skrive klasselaster som bryter delegerings- og unikhetsprinsipper og laster klasse av seg selv.
Kort fortalt følger klasselasteren følgende regel:
- Den sjekker om klassen allerede er lastet inn.
- Hvis klassen ikke er lastet, be den overordnede klasselasteren om å laste klassen.
- Hvis den overordnede klasselasteren ikke kan laste klassen, prøv å laste den i denne klasselasteren.
Tenk på følgende eksempel:
public class Demo { public static void main(String args[]) { System.out.println('How are you?'); } }
Kompiler og kjør koden ovenfor ved å bruke følgende kommando:
javac Demo.java java -verbose:class Demo
-verbose:klasse: Den brukes til å vise informasjon om klasser som lastes av JVM. Det er nyttig når du bruker klasselaster for å laste klasser dynamisk. Følgende figur viser utgangen.
Vi kan observere at kjøretidsklasser som kreves av applikasjonsklassen (Demo) lastes først.
Når klassene er lastet
Det er bare to tilfeller:
- Når den nye bytekoden kjøres.
- Når bytekoden gjør en statisk referanse til en klasse. For eksempel, System.ut .
Statisk vs. dynamisk klasseinnlasting
Klasser er statisk lastet med 'ny' operatør. Dynamisk klasselasting påkaller funksjonene til en klasselaster under kjøring ved å bruke metoden Class.forName().
Forskjellen mellom loadClass() og Class.forName()
loadClass()-metoden laster bare klassen, men initialiserer ikke objektet. Mens Class.forName()-metoden initialiserer objektet etter å ha lastet det. For eksempel, hvis du bruker ClassLoader.loadClass() for å laste JDBC-driveren, tillater ikke klasselasteren å laste JDBC-driveren.
Java.lang.Class.forName()-metoden returnerer klasseobjektet kombinert med klassen eller grensesnitt med det gitte strengnavnet. Den kaster ClassNotFoundException hvis klassen ikke blir funnet.
Eksempel
I dette eksemplet er java.lang.String-klassen lastet inn. Den skriver ut klassenavnet, pakkenavnet og navnene på alle tilgjengelige metoder for String-klassen. Vi bruker Class.forName() i følgende eksempel.
Klasse: Representerer et klasseobjekt som kan være av hvilken som helst type (? er et jokertegn). Klassetypen inneholder metainformasjon om en klasse. For eksempel er typen String.class Class. Bruk Class hvis klassen som modelleres er ukjent.
getDeclaredMethod(): Returnerer en matrise som inneholder Method-objekter som gjenspeiler alle de deklarerte metodene til klassen eller grensesnittet representert av dette klasseobjektet, inkludert offentlig, beskyttet, standard (pakke) tilgang og private metoder, men ekskluderer nedarvede metoder.
getName(): Den returnerer metodenavnet representert av dette metodeobjektet, som en streng.
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(); } } }
Produksjon
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