Este artículo estudia principalmente el contenido relevante de la carga dinámica de Java de JAR y los archivos de clase, de la siguiente manera.
La carga de archivos de clase en Java es dinámico. En otras palabras, solo cargaremos cuando lo usemos, y si no lo usamos, no cargaremos nuestra clase.
Java nos proporciona dos mecanismos dinámicos. El primero es el mecanismo implícito. El segundo es el mecanismo de visualización. como sigue:
Dos métodos:
El método class.forname () tiene dos formularios:
public static Class forName(String className)public static Class forName(String className, boolean initialize,ClassLoader loader) Llamar al método FORNAME () con solo un parámetro es equivalente a class.forname (classname, true, loader).
Ambos métodos deben estar conectados al método nativo FORNAME0 () al final.
FORNAME () Con tres parámetros, la última llamada es: FORNAME0 (nombre, inicializar, cargador);
Ya sea que esté utilizando nuevo para instanciar una determinada clase, o usando el método class.forname () con solo un parámetro, los pasos de "Cargar la clase + ejecución de bloques de código estático" están implícitos en el interior.
Al usar el método class.forname () con tres parámetros, si el segundo parámetro es falso, el cargador de clases solo cargará la clase y no inicializará el bloque de código estático. Solo cuando la clase esté instanciada se inicializará el bloque de código estático. El bloque de código estático se inicializa cuando la clase se instancia por primera vez.
ClassLoader se usa para cargar clase. Cuando se carga una clase, todas las clases a las referencias por esta clase también se cargarán, y esta carga es recursiva. Es decir, si A se refiere a B y B se refiere a C, entonces cuando A se carga, B también se cargará, y cuando B se cargue, C también se cargará. Recursivo así hasta que toda la clase requerida se cargue bien.
paquete com.demo.test; import java.io.bytearRayOutputStream; import java.io.file; import java.io.fileInputStream; import java.io.filenotfoundException; import java.io.ioexception; import java.lang.reflect.field; import java.lang.reflect.invation java.lang.reflect.method; import java.net.malFormedUrLeCeption; import java.net.url; import java.net.urlClassLoader; public class DynamicLoadDemo {enum fileType {jar, class, otro} clase estatica myClassLoader extiende classLoader {public sinquietizado FileNotFoundException {Class<?> cls = findLoadedClass(name);if(cls != null) {return cls;}FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;try {while (true) {len = fis.read (buffer); if (len == -1) {break;} baos.write (buffer, 0, len);} // El descarga de FileInputStream es una operación vacía, porque Flush es la función de escribir cosas en la caché de la entidad (disco duro o flujo de red). No hay necesidad aquí, por lo que está vacío. //baos.flush (); byte [] data = baos.tobyTearRAy (); return de definido definido {fis.close();}catch (IOException e) {e.printStackTrace();}}return null;}}public static void main(String[] args) {String className = "com.demo.test.HelloWorld";String paths[] = { "HelloWorld.jar", "HelloWorld.class" };for (String path : paths) {String LowerPath = Path.tOlowastCase (); fileType fileType = filetype.other; if (LowerPath.endSwith (". Jar") || LowerPath.endSwith (". Zip")) {fileType = fileType.jar;} más si (LowerPath.endswith (". Class")) FileType.other) {return;} archivo archivo = nuevo archivo (path); if (! File.exists ()) {return;} try {url url = file.touri (). Tourl (); system.out.println (url.ToString ()); class <?> Cls = null; switch (filteType) {case jar: ullClassLoader ClassLoader ClassLoader ClassLoader URL[] { url }, Thread.currentThread().getContextClassLoader());cls = classLoader.loadClass(className);break;case CLASS: MyClassLoader myClassLoader = new MyClassLoader();cls = myClassLoader.loadClass(className, file);break;default: break;}if (cls == null) {return;} // campo de instancia variable campo = cls.getDeClaredField ("hello"); if (! Field.isAccessible () {Field.SetAccessible (true);} System.Println (Field.get (Cls.NewInstance ())); // Llamar el método estático sin el método de parámetros STATICMOD = cls.getDeclaredMethod ("saystatichello", nulo); if (! staticMethod.IsAccessible ()) {staticMethod.setAccessible (true);} // Si el valor de retorno de la función es void, nullstaticmethod.invoke (cls, null); // método de instancia con parámetros método = cls.getDeclaredMethod ("decir", cadena); {Method.SetAccessible (true);} objeto retir = método.invoke (cls.newinstance (), "hola world"); system.out.println (ret);} catch (malformedurexception e) {E.PrintStActace ();} Catch (classnotFoundException e) {E.PrintStacktrace ();} {E.PrintStackTrace ();} Catch (SecurityException e) {E.PrintStackTRace ();} Catch (IllegalAccessException e) {E.PrintStackTrace ();} Catch (ILEGALArgumentException e) {E.PrintStActAc. e) {E.PrintStackTrace ();} Catch (nosuchfieldException e) {E.PrintStackTRaceresultado:
Lo anterior es todo el contenido de este artículo sobre el análisis de Java Dynamic de carga JAR e instancias de archivo de clase. Espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!