Saltar al contenido

¿Qué es un ClassLoader de Java?

Solución:

Tomado de este bonito tutorial de Sun:

Motivación

Las aplicaciones escritas en lenguajes de programación compilados estáticamente, como C y C ++, se compilan en instrucciones nativas específicas de la máquina y se guardan como un archivo ejecutable. El proceso de combinar el código en un código nativo ejecutable se llama vinculación: la combinación de código compilado por separado con código de biblioteca compartida para crear una aplicación ejecutable. Esto es diferente en lenguajes de programación compilados dinámicamente como Java. En Java, los archivos .class generados por el compilador de Java permanecen como están hasta que se cargan en la máquina virtual de Java (JVM); en otras palabras, el proceso de vinculación lo realiza la JVM en tiempo de ejecución. Las clases se cargan en la JVM según sea necesario. Y cuando una clase cargada depende de otra clase, esa clase también se carga.

Cuando se inicia una aplicación Java, la primera clase que se ejecuta (o el punto de entrada a la aplicación) es la que tiene un método de vacío estático público llamado main (). Esta clase generalmente tiene referencias a otras clases, y todos los intentos de cargar las clases referenciadas son realizados por el cargador de clases.

Para tener una idea de esta carga de clases recursiva, así como de la idea de carga de clases en general, considere la siguiente clase simple:

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

Si ejecuta esta clase especificando la opción de línea de comandos -verbose: class, de modo que imprima qué clases se están cargando, obtendrá una salida que se ve como sigue. Tenga en cuenta que esto es solo una salida parcial, ya que la lista es demasiado larga para mostrarse aquí.

prmpt>java -verbose:class HelloApp



[Opened C:Program FilesJavajre1.5.0librt.jar]
[Opened C:Program FilesJavajre1.5.0libjsse.jar]
[Opened C:Program FilesJavajre1.5.0libjce.jar]
[Opened C:Program FilesJavajre1.5.0libcharsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

Como puede ver, las clases de tiempo de ejecución de Java requeridas por la clase de aplicación (HelloApp) se cargan primero.

Cargadores de clases en la plataforma Java 2

El lenguaje de programación Java sigue evolucionando para facilitar la vida de los desarrolladores de aplicaciones todos los días. Esto se hace proporcionando API que simplifican su vida al permitirle concentrarse en la lógica empresarial en lugar de los detalles de implementación de los mecanismos fundamentales. Esto es evidente por el reciente cambio de J2SE 1.5 a J2SE 5.0 para reflejar la madurez de la plataforma Java.

A partir de JDK 1.2, un cargador de clases de arranque integrado en la JVM es responsable de cargar las clases del tiempo de ejecución de Java. Este cargador de clases solo carga las clases que se encuentran en la ruta de clases de arranque y, dado que son clases de confianza, el proceso de validación no se realiza como para las clases que no son de confianza. Además del cargador de clases de arranque, la JVM tiene un cargador de clases de extensión responsable de cargar clases desde las API de extensión estándar y un cargador de clases del sistema que carga las clases de una ruta de clases general, así como las clases de su aplicación.

Dado que hay más de un cargador de clases, se representan en un árbol cuya raíz es el cargador de clases de arranque. Cada cargador de clases tiene una referencia a su cargador de clases padre. Cuando se le pide a un cargador de clases que cargue una clase, consulta a su cargador de clases padre antes de intentar cargar el elemento en sí. El padre, a su vez, consulta a su padre, y así sucesivamente. Entonces, es solo después de que todos los cargadores de clases ancestros no pueden encontrar la clase que el cargador de clases actual se involucra. En otras palabras, se utiliza un modelo de delegación.

La clase java.lang.ClassLoader

los java.lang.ClassLoader es una clase abstracta que puede ser subclasificada por aplicaciones que necesitan ampliar la forma en que la JVM carga clases dinámicamente. Constructores en java.lang.ClassLoader (y sus subclases) le permiten especificar un padre cuando crea una instancia de un nuevo cargador de clases. Si no especifica explícitamente un padre, el cargador de clases del sistema de la máquina virtual se asignará como padre predeterminado. En otras palabras, la clase ClassLoader usa un modelo de delegación para buscar clases y recursos. Por lo tanto, cada instancia de ClassLoader tiene un cargador de clases principal asociado, de modo que cuando se solicita encontrar una clase o recursos, la tarea se delega a su cargador de clases principal antes de intentar encontrar la clase o el recurso en sí. los loadClass() El método ClassLoader realiza las siguientes tareas, en orden, cuando se llama para cargar una clase:

Si ya se ha cargado una clase, la devuelve. De lo contrario, delega la búsqueda de la nueva clase al cargador de clases principal. Si el cargador de clases padre no encuentra la clase, loadClass() llama al método findClass() para buscar y cargar la clase. los finalClass() El método busca la clase en el cargador de clases actual si el cargador de clases padre no encontró la clase.


Hay más en el artículo original, que también le muestra cómo implementar sus propios cargadores de clases de red, lo que responde a su pregunta de por qué (y cómo). Consulte también los documentos de la API.

La mayoría de los desarrolladores de Java nunca necesitarán usar explícitamente cargadores de clases (excepto para cargar recursos para que aún funcionen cuando estén empaquetados en JAR), y mucho menos escribir los suyos propios.

Los ClassLoaders se utilizan en grandes sistemas y aplicaciones de servidor para hacer cosas como:

  • Modularice un sistema y cargue, descargue y actualice módulos en tiempo de ejecución
  • Utilice diferentes versiones de una biblioteca de API (por ejemplo, un analizador XML) en paralelo
  • Aísle diferentes aplicaciones que se ejecutan dentro de la misma JVM (asegurándose de que no interfieran entre sí, por ejemplo, a través de variables estáticas)

La pregunta es “¿Por qué debería uno molestarse en que exista esta clase ClassLoader”?

Bueno, sobre todo para que puedas arreglar las cosas si salen mal :-).

Es cierto, siempre que escriba una aplicación, la compile en un JAR y tal vez incluya algunos JAR de biblioteca adicionales, no necesita saber acerca de los cargadores de clases, simplemente funcionará.

Aún así, es útil saber un poco sobre los cargadores de clases y la carga de clases para comprender mejor lo que sucede detrás de escena. Como ejemplo, los “inicializadores estáticos” se ejecutarán cuando se cargue una clase, por lo que para comprender cuándo se ejecutarán, debe saber cómo el cargador de clases decide cuándo cargarlos.

también .. ¿cómo se usa en la práctica?

Para casos simples, no los necesita. Sin embargo, si necesita cargar código dinámicamente en tiempo de ejecución con control explícito de dónde proviene (por ejemplo, cargar en una red, cargar complementos no disponibles en tiempo de compilación, etc.), es posible que deba hacer más. Entonces puede, por ejemplo, escribir su propio cargador de clases. Vea las otras respuestas para los enlaces.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *