2015-12-08 12 views
10

Sono stato confuso con la gerarchia di delega UrlClassLoader e la gerarchia di ereditarietà. Ho creato la classe che estende UrlClassLoader ed eseguito: childOfUrlClassLoader.getParent().getClass().getName() che mi ha dato: sun.misc.Launcher$AppClassLoader. Dopo questo ho fare una visita alla classe di cui sopra (source)Gerarchia di delega e ereditarietà UrlClassLoader

249 static class AppClassLoader extends URLClassLoader { 
     //... 
308  protected synchronized Class<?> loadClass(String name, boolean resolve) 
309   throws ClassNotFoundException 
310  { 
311   // First, check if the class has already been loaded 
312   Class c = findLoadedClass(name); 
313   if (c == null) { 
314    try { 
315     if (parent != null) { 
316      c = parent.loadClass(name, false); 
317  
      // ... 
329   return c; 
330  } 

Poi ho controllato, che è un genitore di AppClassLoader. Presumibilmente ho sun.misc.Launcher$ExtClassLoader e il genitore di ExtClassLoader è null.


ho alcune domande:

1) che carica la mia classe dato che il codice di AppClassLoader.loadClass ha linea

294 return (super.loadClass(name, resolve)); 

Sembra ciclo, non è vero?

2) Perché non ExtClassLoader ha BootstrapClassLoader come genitore, ma ha null?

3) Per quale scopo la classe AppClassLoader estende UrlClassLoader?

risposta

7

La build-in Java ClassLoader delegato-primo modello seguono un modello delegato-first. Ciò significa che un ClassLoader consentirà al suo genitore di caricare una classe prima che provi a caricarla autonomamente. La gerarchia dei caricatori ha il caricatore di bootstrap in alto, seguito dal classloader di estensione, il classloader dell'applicazione. Sotto l'applicazione classloader è possibile trovare URLClassLoaders e qualsiasi altro programma di caricamento creato dall'applicazione.

Il programma di caricamento classe bootstrap può caricare file da rt.jar che contiene le classi java più essenziali, incluse quelle nei pacchetti java.lang, java.io, java.util e java.net. L'estensione classloader carica le classi da altri file jar nell'installazione java. È il classloader dell'applicazione che carica le classi trovate nel classpath e che è il classloader corrente all'avvio di un'applicazione.

Caricamento in azione

Che cosa succede quando un'applicazione vuole caricare un HashMap? Al classloader corrente viene chiesto di caricare la classe HashMap. Prima di tentare qualsiasi cosa, chiede al suo genitore, l'estensione classloader di caricare la classe. A sua volta, l'estensione classloader esegue il delgate al classloader bootstrap che trova la classe in rt.jar e lo carica.

Se la classe da caricare si trova nel percorso di classe, la richiesta passa al programma di caricamento del bootstrap come prima per controllare rt.jar. Il programma di caricamento bootstrap non riesce a trovare la classe, quindi l'attività viene rimandata al programma di caricamento della classe estensione che cerca l'installazione java per la classe. Quando questo non riesce, l'attività ritorna al classloader dell'applicazione che esegue la scansione del classpath per la classe.

Il ClassLoader cache di

In pratica ogni caricamento classe dispone di una cache in cui sono memorizzate le classi già caricate e la cache viene ricercato prima che la delegazione al genitore, ma questo non altera il principio della delega prima.

Questo è dove la cache viene controllato

Class c = findLoadedClass(name); 

URLClassLoaders

Un URLClassLoader creato da un'applicazione avrà la ClassLoader applicazione come un genitore. Se segue il modello first-delegate, le classi verranno trovate nel classpath prima dell'URL fornito.

le domande

1) che carica la mia classe

vedo codice leggermente diverso nel tuo link

309   // First, check if the class has already been loaded 
310   Class c = findLoadedClass(name); 
311   if (c == null) { 
312    try { 
313     if (parent != null) { 
314      c = parent.loadClass(name, false); 
315     } else { 
316      c = findBootstrapClass0(name); 
317     } 
318    } catch (ClassNotFoundException e) { 
319     // If still not found, then invoke findClass in order 
320     // to find the class. 
321     c = findClass(name); 
322    } 
323   } 

Se una classe non è caricato dal genitore, si getta una ClassNotFoundException che viene catturato e consente al ClassLoader corrente di trovare la classe

321     c = findClass(name); 

2) Perché ExtClassLoader non ha BootstrapClassLoader come genitore, ma ha null?

Questa venga risolta dal getClassLoader API

[getClassLoader()] restituisce il caricatore di classe per la classe. Alcune implementazioni possono utilizzare null per rappresentare il caricatore di classe bootstrap.

3) Per quale scopo la classe AppClassLoader estende UrlClassLoader?

Si consideri che il classloader dell'applicazione non è speciale in quanto carica le classi fornite dall'utente, non le classi di sistema. Il classpath è effettivamente un elenco di URI quindi un URLClassLoader è una superclasse adatta.

Riferimenti

Ci sono molti articolo su classloading compreso