La diferencia entre Java y otros lenguajes es que Java se ejecuta en la Máquina Virtual Java (JVM). Esto significa que el código compilado se guarda en un formato independiente de la plataforma, en lugar de un formato que se ejecuta en una máquina específica. Este formato tiene muchas diferencias importantes con respecto al formato de código ejecutable tradicional. Específicamente, a diferencia de un programa C o C++, un programa Java no es un archivo ejecutable independiente, sino que consta de muchos archivos de clases separados, cada archivo de clase correspondiente a una clase Java. Además, estos archivos de clase no se cargan en la memoria inmediatamente, sino que se cargan cuando el programa los necesita. Un cargador de clases es una herramienta utilizada en la máquina virtual Java para cargar clases en la memoria. Además, el cargador de clases de Java también está implementado en Java. De esta manera, puede crear fácilmente su propio cargador de clases sin tener un conocimiento profundo de la máquina virtual Java.
¿Por qué crear un cargador de clases?
Ahora que la máquina virtual Java ya tiene un cargador de clases, ¿necesitamos crear otros nosotros mismos? Buena pregunta. El cargador de clases predeterminado solo sabe cómo cargar clases desde el sistema local. Cuando su programa se compila de forma totalmente nativa, el cargador de clases predeterminado generalmente funciona bien. Pero una de las cosas más interesantes de Java es lo fácil que es cargar clases desde la red en lugar de hacerlo sólo localmente.
Por ejemplo, un navegador puede cargar clases a través de un cargador de clases personalizado. También hay muchas formas de cargar clases. Una de las cosas más interesantes de Java es que puedes personalizarlo además de simplemente desde la red local o:
* Verificar automáticamente las firmas digitales antes de ejecutar código que no sea de confianza
* Descifrar el código según la contraseña proporcionada por el usuario
* Cree clases dinámicamente según las necesidades del usuario. Cualquier cosa que le interese se puede integrar fácilmente en su aplicación en forma de código de bytes. Ejemplos de cargadores de clases personalizados si ha utilizado el appletviewer (navegador de aplicaciones pequeñas) JDK (Java Software Development Kit).
Para los navegadores integrados de Java, ya utiliza un cargador de clases personalizado. Cuando Sun lanzó por primera vez el lenguaje Java, una de las cosas más interesantes fue ver cómo Java ejecutaba el código descargado desde un sitio web remoto. Ejecutar desde un sitio remoto a través de HTTP
El código de bytes transmitido por la conexión P parece un poco extraño. Esto funciona porque Java tiene la capacidad de instalar cargadores de clases personalizados. El navegador de subprogramas contiene un cargador de clases. Este cargador de clases no encuentra clases Java localmente, sino que accede al servidor remoto, carga el archivo de código de bytes original a través de HTTP y luego lo convierte en una clase Java en la máquina virtual Java. Por supuesto, los cargadores de clases hacen muchas otras cosas: bloquean clases Java no seguras y evitan que diferentes subprogramas en diferentes páginas interfieran entre sí. Echidna, un paquete escrito por Luke Gorrie, es un paquete de software Java abierto que permite ejecutar de forma segura múltiples aplicaciones Java en una máquina virtual Java. Evita la interferencia entre aplicaciones mediante el uso de un cargador de clases personalizado para darle a cada aplicación una copia del archivo de clase.
cargador de clases java:
Hay tres cargadores de clases de forma predeterminada en Java: cargador de clases de arranque, cargador de clases de extensión y cargador de clases del sistema (también llamado cargador de clases de aplicación).
Los cargadores de clases son una de las funciones más poderosas de Java. Pero los desarrolladores a menudo se olvidan de cargar los componentes. Un cargador de clases es una clase responsable de buscar y cargar archivos de clases en tiempo de ejecución. Java permite el uso de diferentes cargadores de clases, incluso cargadores de clases personalizados.
Los programas Java contienen muchos archivos de clase, cada uno de los cuales corresponde a una única clase Java. A diferencia de los programas C estáticos, estos archivos de clase se cargan en la memoria una vez y deben cargarse en cualquier momento. Esto es lo que diferencia a los cargadores de clases. Obtiene códigos de bytes independientes de la plataforma de los archivos fuente (generalmente archivos .class o .jar) y luego los carga en el espacio de memoria JVM para que puedan interpretarse y ejecutarse. De forma predeterminada, java.lang.ClassLoader carga cada clase de una aplicación. Como se puede heredar, su funcionalidad se puede mejorar libremente.
Cargador de clases personalizado
importar java.io.*;
importar java.net.*;
importar java.util.*;
importar java.lang.reflect.Method;
clase pública CustomClassLoader extiende URLClassLoader {
private FileInputStream input = null // Flujo de entrada del archivo
private ByteArrayOutputStream out = null // flujo de salida de matriz de bytes
cadena privada [] url = nulo // Ruta de carga del archivo de clase
byte privado [] datos = nulo // Código de bytes del archivo de clase
private String extensionalName = "" //Extensión del archivo de clase
CustomClassLoader público (URL [] URL) arroja una excepción {
super(URL);
this.url = nueva cadena[urls.length];
for (int i = 0; i < urls.length; i++) {
this.url[i] = urls[i].toURI().toString();
}
}
/*
* Analizar URL
*/
setFilePath vacío privado() {
for (int i = 0; i < this.url.length; i++) {
if (this.url[i].substring(0,4).toLowerCase().equals("archivo") == verdadero) {
esta.url[i] = esta.url[i].substring(5);
}
}
}
/*
* Obtenga el código de bytes del archivo con el nombre de clase especificado (nombre del paquete + nombre de clase)
* @nombre nombre Cadena
* @return byte[]
*/
byte privado [] getFileData (nombre de cadena) {
intentar {
this.setFilePath();
para (URL de cadena: this.url) {
String fileName = url + nombre.replace('.', '/').concat(".") +
this.getExtensionalName();
entrada = nuevo FileInputStream (nuevo archivo (nombre de archivo));
si (entrada! = nulo) {
romper;
}
}
salida = nuevo ByteArrayOutputStream();
datos = nuevo byte[1024];
int longitud = -1;
mientras ((len = input.read(datos)) != -1) {
out.write(datos, 0, len);
}
datos = out.toByteArray();
} captura (Excepción e) {
e.printStackTrace();
} finalmente {
intentar {
si (entrada! = nulo)
entrada.cerrar();
si (¡fuera! = nulo)
fuera.cerrar();
datos de devolución;
} captura (Excepción e) {
e.printStackTrace();
devolver nulo;
}
}
}
/*
* Buscar archivos de clase según el nombre de clase especificado
* @param nombre Cadena
* Clase @return
*/
Clase protegida findClassByName (nombre de cadena) {
intentar {
byte[] datos = this.getFileData(nombre);
si (datos == nulo) {
devolver nulo;
}
devuelve this.defineClass(nombre, datos, 0, datos.longitud);
} captura (Excepción e) {
e.printStackTrace();
devolver nulo;
}
}
/*
* Anular el método loadClass()
* @param nombre Cadena
* Clase @return
*/
clase pública loadClass (nombre de cadena) {
Clase c = nula;
intentar {
c = super.loadClass(nombre);
} captura (ClassNotFoundException e) {
e.printStackTrace();
} finalmente {
if (c == null) // Cuando el método predeterminado de la clase principal no está cargado en la clase especificada, use un método personalizado para encontrarlo
c = this.findClassByName(nombre);
devolver c;
}
}
cadena pública getExtensionalName() {
devolver nombre extensible;
}
setExtensionalName público vacío (String extensionalName) {
this.extensionalName = extensionalName;
}
public static void main (String [] args) lanza una excepción {
URL[] url = new URL[] {new URL("file:e:/")} //Agrega la ruta a la clase que deseas cargar.
//Puede ser de red o local
CustomClassLoader csl = nuevo CustomClassLoader(url);
csl.setExtensionalName("rs");
Clase c1 = csl.loadClass("com.demo");
Objeto obj = c1.newInstance();
Método método = c1.getMethod("printText", null);
método.invoke(obj, nulo);
}