Carga de clase Java

¿Cómo funciona Compile Once, Run Anywhere?

Inserte la descripción de la imagen aquí

Cómo carga JVM archivos .class

máquina virtual de Java

Inserte la descripción de la imagen aquí
Cargador de clases: carga archivos de clases en la memoria de acuerdo con un formato específico
Área de datos en tiempo de ejecución: modelo de estructura de memoria JVM
Motor de ejecución: comandos de análisis
Interfaz nativa: Java utiliza bibliotecas nativas que integran diferentes lenguajes de desarrollo

reflexión

El mecanismo de reflexión de Java está en estado de ejecución, para cualquier clase, puede conocer todas las propiedades y métodos de esta clase; para cualquier objeto, puede llamar a cualquiera de sus métodos y propiedades] Tipos de métodos para obtener información de forma dinámica y llamar a objetos de forma dinámica La función se denomina mecanismo de reflexión del lenguaje java.

package reflect;

public class Robot {
    
    
    private String name;

    public void sayHi(String helloSentence) {
    
    
        System.out.println(helloSentence + " " + name);
    }

    private String throwHello(String tag) {
    
    
        return "Hello " + tag;
    }


}

package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectSample {
    
    
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    
    
        Class clazz=Class.forName("reflect.Robot");
        Robot robot= (Robot) clazz.newInstance();
        System.out.println("Class name is "+clazz.getName());
        //私有方法调用
        //获取类中声明的方法
        Method getHello=clazz.getDeclaredMethod("throwHello", String.class);
        getHello.setAccessible(true);
        Object str=getHello.invoke(robot,"Tom");
        System.out.println("getHello result is"+str);

        //获取所有公共的方法
        Method sayHi=clazz.getMethod("sayHi", String.class);
        sayHi.invoke(robot,"Welcome");

        //获取声明的属性
        Field name=clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(robot,"Alice");
        sayHi.invoke(robot,"Welcome");
    }
}

El proceso de la clase desde la compilación hasta la ejecución.

  • El compilador compila los archivos fuente Robot.java en objetos de código de bytes Robot.class
  • ClassLoader convierte el código de bytes en objetos de clase JVM
  • JVM usa el objeto Class para crear una instancia del objeto Robot

ClassLoader

ClassLoader juega un papel muy importante en Java. Trabaja principalmente en la etapa de carga de clases. Su función principal es obtener flujos de datos binarios de clases desde fuera del sistema. Es el componente central de Java. Todas las clases son cargadas por ClassLoader. ClassLoader Responsable de cargar el flujo de datos binarios en el archivo Class en el sistema y luego entregarlo a la máquina virtual Java para la conexión, inicialización y otras operaciones.

Tipos de ClassLoader

BootStrapClassLoader: escrito en C ++, cargando la biblioteca central java. *
ExtClassLoader: escrito en Java, cargando la biblioteca extendida javax. *
AppClassLoader: escrito en Java, el directorio donde se encuentra el cargador.
Custom ClassLoader: escrito en Java, carga personalizada

Implementación de ClassLoader personalizado

La función clave
findClass
defineClass

Defina una clase fuera del proyecto y compílela en un archivo de clase usando javac

public class Wali {
    
    
	static{
    
    
		System.out.println("Hello, Wali!");
	}
}

Cargador de clases personalizado

package customclassloader;

import java.io.*;

//自定义类加载器
public class MyClassLoader extends ClassLoader {
    
    
    private String path;
    private String classLoaderName;

    public MyClassLoader(String path, String classLoaderName) {
    
    
        this.path = path;
        this.classLoaderName = classLoaderName;
    }

    //用于寻找类文件
    @Override
    public Class findClass(String name) {
    
    
        byte[] b = loadClassData(name);
        return defineClass(name, b, 0, b.length);
    }

    //用于加载类文件
    private byte[] loadClassData(String name) {
    
    
        name = path + name + ".class";
        InputStream in = null;
        ByteArrayOutputStream out = null;
        try {
    
    
            in = new FileInputStream(new File(name));
            out = new ByteArrayOutputStream();
            int i = 0;
            while ((i = in.read()) != -1) {
    
    
                out.write(i);
            }

        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                out.close();
                in.close();
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
        }
        return  out.toByteArray();
    }
}

Escribir clase de prueba

package customclassloader;

public class ClassLoaderChecker {
    
    
    public static void main(String[] args) throws Exception {
    
    
        MyClassLoader m=new MyClassLoader("D:\\MyData\\","myClassLoader");
        Class c=m.loadClass("Wali");
        System.out.println(c.getClassLoader());
        c.newInstance();//触发静态代码块
    }
}

Mecanismo de delegación principal del cargador de clases

Inserte la descripción de la imagen aquí

  1. Compruebe si la clase se carga de abajo hacia arriba
  2. Intenta cargar la clase de arriba a abajo

Por qué utilizar el mecanismo de delegación principal para cargar clases

  • Evite cargar varias copias del mismo código de bytes

Cómo se carga la clase

  • Carga implícita: nuevo
  • Carga explícita: loadClass, forName

La diferencia entre loadClass y forName

  • La clase obtenida por Class.forName ha sido inicializada
  • La clase obtenida por Classloder.loadClass aún no está vinculada.

Supongo que te gusta

Origin blog.csdn.net/yasuofenglei/article/details/104218137
Recomendado
Clasificación