Cargador de clases en Java

El Java ClassLoader es una parte del entorno de tiempo de ejecución de Java que carga dinámicamente las clases de Java en la máquina virtual de Java . El sistema de tiempo de ejecución de Java no necesita conocer los archivos y los sistemas de archivos debido a los cargadores de clases.

Las clases de Java no se cargan en la memoria de una sola vez, sino cuando lo requiere una aplicación. En este punto, el JRE llama al Java ClassLoader y estos ClassLoaders cargan las clases en la memoria dinámicamente.

Tipos de ClassLoaders en Java

No todas las clases se cargan con un solo ClassLoader. Dependiendo del tipo de clase y la ruta de la clase, se decide el ClassLoader que carga esa clase en particular. Para conocer el ClassLoader que carga una clase se utiliza el método getClassLoader() . Todas las clases se cargan en función de sus nombres y, si alguna de estas clases no se encuentra, devuelve NoClassDefFoundError o ClassNotFoundException .

Un Java Classloader es de tres tipos :

  1. BootStrap ClassLoader: un cargador de clases Bootstrap es un código de máquina que inicia la operación cuando la JVM lo llama. No es una clase java. Su trabajo es cargar el primer ClassLoader de Java puro. Bootstrap ClassLoader carga clases desde la ubicación rt.jar . Bootstrap ClassLoader no tiene ClassLoaders principales. También se denomina Primodial ClassLoader .
  2. Extensión ClassLoader: la extensión ClassLoader es un elemento secundario de Bootstrap ClassLoader y carga las extensiones de las clases principales de Java desde la biblioteca de extensión JDK respectiva. Carga archivos desde el directorio jre/lib/ext o cualquier otro directorio señalado por la propiedad del sistema java.ext.dirs .
  3. System ClassLoader: un ClassLoader de aplicación también se conoce como System ClassLoader. Carga las clases de tipo de aplicación que se encuentran en la variable de entorno CLASSPATH, -classpath o la opción de línea de comando -cp . Application ClassLoader es una clase secundaria de Extension ClassLoader.

Nota : El modelo de jerarquía de delegación de ClassLoader siempre funciona en el orden Application ClassLoader->Extension ClassLoader->Bootstrap ClassLoader. El Bootstrap ClassLoader siempre tiene la prioridad más alta, el siguiente es Extension ClassLoader y luego Application ClassLoader.

Principios de funcionalidad de un Java ClassLoader

Los principios de funcionalidad son el conjunto de reglas o características sobre las que trabaja un Java ClassLoader. Hay tres principios de funcionalidad , ellos son:

  1. Modelo de delegación : la máquina virtual de Java y el cargador de clases de Java utilizan un algoritmo denominado algoritmo de jerarquía de delegación para cargar las clases en el archivo de Java.

    El ClassLoader funciona en base a un conjunto de operaciones dadas por el modelo de delegación. Están:

    • ClassLoader siempre sigue el principio de jerarquía de delegación .
    • Cada vez que JVM se encuentra con una clase, verifica si esa clase ya está cargada o no.
    • Si la clase ya está cargada en el área del método, la JVM continúa con la ejecución.
    • Si la clase no está presente en el área del método, la JVM le pide al subsistema Java ClassLoader que cargue esa clase en particular, luego el subsistema ClassLoader entrega el control a Application ClassLoader .
    • Luego, Application ClassLoader delega la solicitud a Extension ClassLoader y Extension ClassLoader , a su vez, delega la solicitud a Bootstrap ClassLoader .
    • Bootstrap ClassLoader buscará en el classpath de Bootstrap (JDK/JRE/LIB). Si la clase está disponible, se carga; si no, la solicitud se delega a Extension ClassLoader.
    • Extension ClassLoader busca la clase en Extension Classpath (JDK/JRE/LIB/EXT). Si la clase está disponible, entonces se carga; si no, la solicitud se delega a Application ClassLoader.
    • Application ClassLoader busca la clase en Application Classpath. Si la clase está disponible, se carga; si no, se genera una excepción ClassNotFoundException .

  2. Principio de visibilidad : el principio de visibilidad establece que una clase cargada por un cargador de clases principal es visible para los cargadores de clases secundarios, pero una clase cargada por un cargador de clases secundario no es visible para los cargadores de clases principales. Supongamos que una clase GEEKS.class ha sido cargada por Extension ClassLoader, entonces esa clase solo es visible para Extension ClassLoader y Application ClassLoader pero no para Bootstrap ClassLoader. Si esa clase se intenta cargar nuevamente usando Bootstrap ClassLoader, da una excepción java.lang.ClassNotFoundException .
  3. Propiedad de unicidad : la propiedad de unicidad garantiza que las clases sean únicas y que no haya repetición de clases. Esto también asegura que las clases cargadas por los cargadores de clases principales no sean cargadas por los cargadores de clases secundarios. Si el cargador de clases principal no puede encontrar la clase, solo entonces la instancia actual intentará hacerlo por sí misma.

Métodos de Java.lang.ClassLoader

Después de que la JVM solicite la clase, se deben seguir algunos pasos para cargar una clase. Las clases se cargan según el modelo de delegación, pero existen algunos métodos o funciones importantes que desempeñan un papel vital en la carga de una clase.

  1. loadClass(String name, boolean resolve) : este método se utiliza para cargar las clases a las que hace referencia la JVM. Toma como parámetro el nombre de la clase. Este es de tipo loadClass(String, boolean).
  2. defineClass() : El método defineClass() es un método final y no se puede anular. Este método se usa para definir una array de bytes como una instancia de clase. Si la clase no es válida, arroja ClassFormatError .
  3. findClass(String name) : este método se usa para encontrar una clase específica. Este método solo encuentra pero no carga la clase.
  4. findLoadedClass(String name) : este método se usa para verificar si la clase a la que hace referencia la JVM se cargó previamente o no.
  5. Class.forName(String name, boolean initialize, ClassLoader loader) : este método se utiliza para cargar la clase y para inicializarla. Este método también da la opción de elegir cualquiera de los ClassLoaders. Si el parámetro ClassLoader es NULL, se utiliza Bootstrap ClassLoader.

Ejemplo: el siguiente código se ejecuta antes de que se cargue una clase:

protected synchronized Class<?>
loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    Class c = findLoadedClass(name);
    try {
        if (c == NULL) {
            if (parent != NULL) {
                c = parent.loadClass(name, false);
            }
            else {
                c = findBootstrapClass0(name);
            }
        }
        catch (ClassNotFoundException e)
        {
            System.out.println(e);
        }
    }
}

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

Publicación traducida automáticamente

Artículo escrito por DannanaManoj y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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