[Java] Descripción general de Reflection 01

Reflexion

Reflection permite que un programa use ReflectionAPI para obtener información interna de cualquier clase durante la ejecución y manipular directamente las propiedades y métodos internos de cualquier objeto

 

Después de cargar la clase, se genera un objeto de tipo Clase en el área de método de la memoria de almacenamiento dinámico

¡Presta atención! Una clase solo puede tener una instancia correspondiente del tipo de clase

Este objeto encapsula la información estructural completa de la clase, puede ver la estructura de la clase a través de este objeto de clase

 

La diferencia entre lenguaje dinámico y lenguaje estático:

Lenguaje dinamico

El lenguaje de la estructura se puede cambiar en tiempo de ejecución, y se pueden agregar nuevas funciones, objetos y código en tiempo de ejecución

Las funciones existentes se pueden eliminar o modificar, y el código de tiempo de ejecución puede cambiar la estructura de acuerdo con ciertas condiciones

Lenguajes principales: Object-C, C #, JavaScript, PHP, Python, Eriang

Lenguaje estático

El lenguaje de programación que no puede cambiar el código en tiempo de ejecución es el lenguaje estático: Java, C, C ++

Aunque Java es un lenguaje estático, ¡el mecanismo de reflexión puede hacer que Java se vea dinámico! ! !

 

Funciones proporcionadas por el mecanismo de reflexión:

-Determinar la clase a la que pertenece el objeto

-Crear instancias de clases en tiempo de ejecución

-Determinar todas las variables miembro y métodos de una clase

-Obtener información genérica

-Llamadas miembros variables y métodos de cualquier instancia

- Manejar anotaciones en tiempo de ejecución

-Proxy dinámico! ! !

 

API

-java.lang.Class clase tipo clase

-java.lang.reflect.Method clase de método

-java.lang.reflect.Field clase de campo

-java.lang.reflect.Construtor clase constructora

 

Declaramos una clase personalizada

 Persona de clase pública {
     nombre de cadena privada ;
    int int privado  ;
    género booleano privado ; public Person () { 
    } public Person (String name, int age, boolean gender) {
         this .name = name;
        this .age = age;
        este .gender = género; 
    } public String getName () {
         return name; 
    } public void setName (String name) {
         esto 

    

    

    

     .name = nombre; 
    } 

    public  int getAge () {
         return age; 
    } 

    public  void setAge ( int age) {
         this .age = age; 
    } 

    public  boolean isGender () {
         return gender; 
    } 

    public  void setGender ( género booleano ) {
         this .gender = gender; 
    } 

    @Override 
    public String toString () {
         return "Persona {" + 
                "name = '" + name +' \ '' + 
                ", age =" + age + 
                ", gender =" + gender + 
                '}' ; 
    } 
}

 

A través de la reflexión para lograr acceso a las operaciones de clase e instancia

public  class ReflectTest { 

    @Test 
    public  void reflect () arroja la excepción {
         // El atributo de clase puede devolver el objeto de clase de esta clase 
        Class <Person> personClass = Person. class ; 

        // Obtener el objeto de la clase de constructor de esta clase, obtenido aquí Es un constructor de parámetros completo 
        Constructor <Person> personClassConstructor = personClass.getConstructor (String. Class , int . Class , boolean . Class ); 

        // Llame al constructor para crear un objeto 
        Person Person person = personClassConstructor.newInstance ("杰哥", 28 , verdadero ); 

        //Llamar a toString () del objeto Person; 
        System.out.println (person.toString ()); 

        // Mediante la reflexión, llame a la propiedad especificada por el objeto, método 
        Field age = personClass.getDeclaredField ("age" ); 
        
        // Desbloquear acceso Los permisos deben establecerse antes del acceso, de lo contrario no tiene sentido 
        age.setAccessible ( true ); 

        // A través de la instancia de campo de clase de la clase, llame al campo de edad de instancia de parámetro, modifique el valor
         // encontrado un error de excepción privado no se puede acceder
         // Clase cn.dai.Reflection .ReflectTest no puede acceder a un miembro de la clase cn.dai.Reflection.Person con modificadores "privados" 
        age.set (persona, 10 ); 
        System.out.println (persona); 
    } 
}

Por ejemplo, métodos, constructores, estos son básicamente para obtener la clase de encapsulación correspondiente, obtener una instancia de la clase de encapsulación y luego llamar al método,

Si se trata de un derecho de acceso modificado de forma privada, configure la accesibilidad de la instancia encapsulada antes de usarla y luego ejecute la llamada

 

Proceso de carga de clase:

-Después de que el bytecode pasa por java.exe, se generarán uno o más archivos de bytecode de acuerdo con el contenido escrito por el código fuente

-java.exe interpretará y se ejecutará de acuerdo con un archivo de bytecode == bytecode se carga en la memoria

-Este paso anterior se llama carga de clase

-La clase cargada en la memoria, llamada clase de tiempo de ejecución, existe como una instancia de la clase Class

-Conversamente, el objeto de Class es una clase de bytecode que se ejecuta en la JVM

 

Cuatro formas de obtener instancias de clase:

public  class GetClassStyle { 

    @Test 
    public  void getClass4Way () lanza Exception {
         // first 
        class.class Class <Person> personClass1 = Person. class ; 
        System.out.println (personClass1); 

        // instancia de la segunda clase.getClass ( ); 
        la Persona Persona = nuevo nuevo la Persona (); 
        la clase <? la extiende personClass2 la Persona => person.getClass (); 
        System.out.println (personClass2); 

        // tercer Class.forName nombre completo (la) clase 
        clase < ?> personClass3 = Class.forName ("cn.dai.Reflection.Person"); 
        System.out.println (personClass3); 

        // Cuarta clase actual. Class.getClassLoader (). LoadClass (nombre completo de la clase "); 
        Class <?> PersonClass4 = GetClassStyle. Class .getClassLoader (). LoadClass ("cn.dai.Reflection.Person" ); 
        
        // Todas las instancias del método llamado son el mismo objeto 
    } 
}

 

Use ClassLoader para cargar archivos de configuración

public  class Loader { 

    @Test 
    public  void loader () lanza Exception { 
        Properties properties = new Properties ();
         // El objeto Stream solo puede leerse en el directorio del proyecto fuente actual. Si desea leer, la ruta debe escribirse como "src \" \ jdbc.properties " 
        FileInputStream inputStream = new FileInputStream (" jdbc.properties " ); 
        properties.load (inputStream); 
        String driver = properties.getProperty (" driver " ); 
        String url = properties.getProperty (" url " ); 
        String username = properties.getProperty ("nombre de usuario" );
        String password = properties.getProperty ("contraseña" ); 
        System.out.println (controlador); 
        System.out.println (url); 
        System.out.println (nombre de usuario); 
        System.out.println (contraseña); 
        inputStream. close (); 
    } 

    @Test 
    public  void loader2 () lanza Exception {
         // Crear instancia de configuración 
        Propiedades propiedades = nuevas Propiedades ();
         // La ubicación donde el cargador de clases lee el archivo por defecto es 
        InputStream en el Módulo actual o paquete de proyecto src inputStream = Loader. class .getClassLoader (). getResourceAsStream ("jdbc.properties" );
        // 加载
        properties.load (flujoEntrada); 

        // 读取 信息 
        String driver = properties.getProperty ("driver" ); 
        String url = properties.getProperty ("url" ); 
        String username = properties.getProperty ("nombre de usuario" ); 
        Cadena contraseña = propiedades.getProperty ("contraseña" ); 

        System.out.println (controlador); 
        System.out.println (url); 
        System.out.println (nombre de usuario); 
        System.out.println (contraseña); 
        
        inputStream.close (); 
    } 

    @Test 
    public  void loader3 () lanzaExcepción {
         // Crear una instancia de configuración 
        Propiedades de propiedades = nuevas Propiedades ();
         // Codificación de URL de retorno% 20 La ubicación del cargador de clases para leer el archivo está por defecto en el Módulo actual o paquete src del proyecto Ruta de 
        cadena = Cargador. Clase .getClassLoader () .getResource ("jdbc.properties" ) .getFile ();
         // Necesita decodificar 
        String decode = URLDecoder.decode (ruta, "UTF-8" );
         // Crear objeto de flujo 
        InputStream inputStream = nuevo FileInputStream (decode);
         // Cargar configuración 
        properties.load (inputStream); 

        // Leer información 
        String driver = properties.getProperty ("driver"); 
        String url = properties.getProperty ("url" ); 
        String username = properties.getProperty ("nombre de usuario" ); 
        Cadena contraseña = propiedades.getProperty ("contraseña" ); 

        System.out.println (controlador); 
        System.out.println (url); 
        System.out.println (nombre de usuario); 
        System.out.println (contraseña); 
        
        inputStream.close (); 
    } 
}

 

 Crear un objeto de la clase de tiempo de ejecución

    @Test
     public  void getInstanceByReflect () lanza Exception { 
        Class <Person> personClass = Person. Class ; 

        // Crea un objeto directamente desde la instancia de clase de la clase . No se recomienda usar este método en JDK9 + y posterior.
         // newInstance (); llamada interna El constructor de parámetros nulos en tiempo de ejecución, no hay construcción de parámetros nulos, la excepción de llamada
         // la clase de tiempo de ejecución debe proporcionar un constructor de parámetros nulos, los permisos de acceso no deben ser inferiores al predeterminado 
        
        // javaBean requiere una razón de constructor de parámetros vacía:
         // a través de esto Reflexione para llamar al constructor para crear una instancia de Bean
         // Cuando la subclase hereda la clase de tiempo de ejecución, llame a super () para asegurarse de que la clase principal también tenga este constructor 
        
        Person person = personClass.newInstance (); 
        System.out.println (person); 
    }

 

La naturaleza dinámica de la reflexión genera dinámicamente ejemplos.

    @Test
     public  void dynamic () arroja ClassNotFoundException, IllegalAccessException, InstantiationException {
         para ( int i = 0; i <100; i ++ ) {
             int random = new Random (). NextInt (3 ); 
            Cadena classPath = nulo ;
            conmutador (aleatorio) {
                 caso 0 : 
                    classPath = "java.util.Date" ;
                    romper ;
                caso 1 :
                    classPath = "java.lang.Object" ;
                    romper ;
                caso 2 : 
                    classPath = "cn.dai.Reflection.Person" ; 
            } 

            Class <?> Name = Class.forName (classPath); 
            Objeto instancia = nombre.nuevoInstance (); 
            System.out.println (instancia); 
        } 
    }

 

Supongo que te gusta

Origin www.cnblogs.com/mindzone/p/12757474.html
Recomendado
Clasificación