[Java] Overview of Reflection 01

Reflection

Reflection allows a program to use the ReflectionAPI to obtain internal information of any class during execution, and directly manipulate the internal properties and methods of any object

 

After loading the class, an object of type Class is generated in the method area of ​​heap memory

pay attention! A class can only have one corresponding instance of the class type

This object encapsulates the complete structural information of the class, you can see the structure of the class through this class object

 

The difference between dynamic language and static language:

Dynamic language

The language of the structure can be changed at runtime, and new functions, objects, and code can be added at runtime

Existing functions can be deleted or modified, and the runtime code can change the structure according to certain conditions

Main languages: Object-C, C #, JavaScript, PHP, Python, Eriang

Static language

The programming language that cannot change the code at runtime is the static language: Java, C, C ++

Although Java is a static language, the reflection mechanism can make Java look dynamic! ! !

 

Functions provided by the reflection mechanism:

-Determine the class to which the object belongs

-Create instances of classes at runtime

-Determine all the member variables and methods of a class

-Get generic information

-Call member variables and methods of any instance

-Handle annotations at runtime

-Dynamic proxy! ! !

 

API

-java.lang.Class class type class

-java.lang.reflect.Method method class

-java.lang.reflect.Field field class

-java.lang.reflect.Construtor constructor class

 

We declare a custom class

public class Person {
    private String name;
    private int age;
    private boolean gender;

    public Person() {
    }

    public Person(String name, int age, boolean gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    public boolean isGender() {
        return gender;
    }

    public void setGender(boolean gender) {
        this.gender = gender;
    }

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

 

Through reflection to achieve access to the class and instance operations

public  class ReflectTest { 

    @Test 
    public  void reflect () throws Exception {
         // The class attribute can return the class object of this class 
        Class <Person> personClass = Person. class ; 

        // Get the object of the constructor class of this class, obtained here It is a full parameter constructor 
        Constructor <Person> personClassConstructor = personClass.getConstructor (String. Class , int . Class , boolean . Class ); 

        // Call the constructor to create a Person object 
        Person person = personClassConstructor.newInstance ("杰哥", 28 , true ); 

        //Call toString () of Person object; 
        System.out.println (person.toString ()); 

        // Through reflection, call the property specified by the object, method 
        Field age = personClass.getDeclaredField ("age" ); 
        
        // Unlock access Permissions must be set before access, otherwise it is meaningless 
        age.setAccessible ( true ); 

        // Through the class field instance of the class, call the parameter instance age field, modify the value
         // found an exception error private cannot be accessed
         // Class cn.dai.Reflection .ReflectTest can not access a member of class cn.dai.Reflection.Person with modifiers "private" 
        age.set (person, 10 ); 
        System.out.println (person); 
    } 
}

For example, methods, constructors, these are basically to obtain the corresponding encapsulation class, get an instance of the encapsulation class, and then call the method,

If it is a privately modified access right, set the accessibility of the encapsulated instance before use, and then execute the call

 

Class loading process:

-After the bytecode goes through java.exe, one or more bytecode files will be generated according to the content written by the source code

-java.exe will interpret and run according to a bytecode file == bytecode is loaded into memory

-This step above is called class loading

-The class loaded into memory, called the runtime class, exists as an instance of the Class class

-Conversely, the object of Class is a bytecode class running in the JVM

 

Four ways to obtain Class instances:

public  class GetClassStyle { 

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

        // instance of the second class.getClass ( ); 
        the Person Person = new new the Person (); 
        class <? the extends personClass2 the Person => person.getClass (); 
        System.out.println (personClass2); 

        // third Class.forName fully qualified name (the class) 
        class < ?> personClass3 = Class.forName ("cn.dai.Reflection.Person"); 
        System.out.println (personClass3); 

        // Fourth current class. Class.getClassLoader (). LoadClass (fully qualified name of the class "); 
        Class <?> PersonClass4 = GetClassStyle. Class .getClassLoader (). LoadClass ("cn.dai.Reflection.Person" ); 
        
        // All instances of the called method are the same object 
    } 
}

 

Use ClassLoader to load configuration files

public  class Loader { 

    @Test 
    public  void loader () throws Exception { 
        Properties properties = new Properties ();
         // Stream object can only be read in the current source project directory. If you want to read, the path should be written as "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 ("username" );
        String password = properties.getProperty ("password" ); 
        System.out.println (driver); 
        System.out.println (url); 
        System.out.println (username); 
        System.out.println (password); 
        inputStream. close (); 
    } 

    @Test 
    public  void loader2 () throws Exception {
         // Create configuration instance 
        Properties properties = new Properties ();
         // The location where the class loader reads the file defaults to the 
        InputStream under the current Module or project src package inputStream = Loader. class .getClassLoader (). getResourceAsStream ("jdbc.properties" );
        // 加载
        properties.load(inputStream);

        // 读取信息
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println(driver);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
        
        inputStream.close();
    }

    @Test
    public void loader3() throwsException {
         // Create a configuration instance 
        Properties properties = new Properties ();
         // Return the URL encoding% 20 The location of the class loader to read the file is by default under the current Module or project src package 
        String path = Loader. Class .getClassLoader () .getResource ("jdbc.properties" ) .getFile ();
         // Need to decode 
        String decode = URLDecoder.decode (path, "UTF-8" );
         // Create stream object 
        InputStream inputStream = new FileInputStream (decode);
         // Load configuration 
        properties.load (inputStream); 

        // Read information 
        String driver = properties.getProperty ("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println(driver);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
        
        inputStream.close();
    }
}

 

 Create an object of the runtime class

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

        // Create an object directly from the class instance of the class . This method is not recommended to be used in JDK9 + and later.
         // newInstance (); internal call The null parameter constructor at run time, there is no null parameter construction, call exception
         // runtime class must provide a null parameter constructor, access permissions should not be lower than the default 
        
        // javaBean requires an empty parameter constructor reason:
         // through this Reflect to call the constructor to create an instance of Bean
         // When the subclass inherits the runtime class, call super () to ensure that the parent class also has this constructor 
        
        Person person = personClass.newInstance (); 
        System.out.println (person); 
    }

 

The dynamic nature of reflection, dynamically generate examples

    @Test
    public void dynamic() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        for (int i = 0; i < 100; i++) {
            int random = new Random().nextInt(3);
            String classPath = null;
            switch (random){
                case 0:
                    classPath = "java.util.Date";
                    break;
                case 1:
                    classPath = "java.lang.Object";
                    break;
                case 2:
                    classPath = "cn.dai.Reflection.Person";
            }

            Class<?> name = Class.forName(classPath);
            Object instance = name.newInstance();
            System.out.println(instance);
        }
    }

 

Guess you like

Origin www.cnblogs.com/mindzone/p/12757474.html