JAVA reflection

Overview of JAVA reflection

1.1 Application of reflection technology

1) What is it? (a set of apis for manipulating bytecode objects) (Advantage: Flexible – can’t predict the future, but can handle it.) 3) Reflex starting point? (Objects of Class type)

1.2 Specific application of reflection?

1) Get the Constructor object and build an instance of the class based on it. Why don’t you just go new? 3) Get the Method in the class and call the Method using reflection technology. 4) Get the Annotation on the class and get the content in the Annotation. 5) Get the package of the class and find the class under the specified package based on the package. Recognition + aggressive execution == successful delivery



1.3 Static vs. Dynamic languages

1.3.1 Dynamic languages

A language whose structure can be changed at run time: for example, new functions, objects, and even code can be introduced, existing functions can be deleted, or other structural changes can be made. In layman’s terms, code can change its structure at run time depending on certain conditions. l

  • Main dynamic languages :Object-C, C#, Javasoript, PHP, Python, etc.

1.3.2 Static languages

The equivalent of dynamic languages, languages with immutable run-time structures, are static languages. Such as Java, C, C++. Java is not a dynamic language, but Java can be called a “quasi-dynamic language.” That is, Java is dynamic, and we can use reflection to get features like dynamic languages. The dynamic nature of Java makes programming more flexible!

1.4 Java Reflection

Reflection is the key to Java being considered a dynamic language. Reflection allows programs to use Reflection APl to retrieve the internal information of any class and manipulate the internal properties and methods of any object during execution.

  • Class c = Class.forName(“java.lang.String”)

After the Class is loaded, an object of type Class (one Class object per Class) is generated in the method area of heap memory, which contains the complete structure information of the Class. We can see the structure of the class through this object. This object is like a mirror through which you can see the structure of the class, so we call it a reflection.

1.4.1 Functions provided by Java Reflection

➢ at run time to judge any ➢ an object belonging to the class at run time to construct any of a class object ➢ at run time to judge any one class member variables and methods are ➢ generic type information at run time ➢ at runtime call any member variables of an object and method ➢ processing annotations ➢ generating dynamic proxy at runtime

1.4.2 Advantages and disadvantages of Java reflection

Advantages: Dynamic object creation and compilation can be achieved, showing great flexibility. Disadvantage: Performance impact. Using reflection is basically an interpretation operation where we can tell the JVM what we want to do and it meets our requirements. This type of operation is always slower than performing the same operation directly.

package com.cy.java.oop;
// What is reflection
public class lianxi extends Object {
    public static void main(String[] args) throws ClassNotFoundException {
        // Get the class object of the class by reflection
        Class c1=Class.forName("com.kuang.reflection.User");
        System.out.println(c1);

        Class c2=Class.forName("com.kuang.reflection.User");
        Class c3=Class.forName("com.kuang.reflection.User");
        Class c4=Class.forName("com.kuang.reflection.User");

        // A Class has only one Class object in memory
        // After a Class is loaded, the entire structure of the Class is encapsulated in a Class objectSystem.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); }}// entity class :pojo/ebtity
class User{
    private String name;
    private int id;
    private int age;
    public User(a){}public User(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
    public String getName(a) {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId(a) {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getAge(a) {
        return age;
    }
    public void setAge(int age) {
        this.age = age; }}Copy the code

Second, understand the Class Class and get the Class instance

The following methods are defined in the Object class, which are inherited by all subclasses

  • public final Class getClass()

The return type of the above method is a Class Class. This Class is the source of Java reflection. In fact, the so-called reflection can be understood from the results of the program.

2.1 CLass CLass

Objects can look in the mirror and get information about a class’s properties, methods and constructors, and what interfaces a class implements. For each Class, the JRE reserves an invariant object of type Class for it. A Class object contains a particular structure (Class/interface/enum/annotation/primitive type/void /]) of the relevant information.

Preparation of a loaded Class object by a single instance of a Class in the JVM Such Class is the source of Reflection. For any Class that you want to dynamically load and run, you must obtain the corresponding Class object first

2.2 Common methods of Class

A) If a specific class is known, the method is the most secure and reliable with the highest program performance by obtaining the class attribute of the class.

Class clazz = Person.class;

B) Call getClass of a given instance of a Class to get the Class object

Class clazz = person.getClass();

C) The full Class name of a Class is known, and the Class is on the classpath. The static method forName() of the Class may throw a ClassNotFoundException

Class clazz = Class forName(“demo01.Student”);

D) Built-in basic data types can be directly used by the class name. Type e) can also use classloader which we’ll talk about later

package com.cy.java.oop;


// Test how the class class is created
public class lianxi {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("This man is :"+person.name);
        // Method 1: Obtain from objects
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        // Method 2: obtain by forname
        Class c2 = Class.forName("com.cy.java.oop.Student");
        System.out.println(c2.hashCode());

        // Method 3: Use the class name. Class
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

        // The basic built-in wrapper classes all have a Type attribute
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        // Get the parent typeClass c5 = c1.getSuperclass(); System.out.println(c5); }}class Person{
    public String name;
    public Person(a){}

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString(a) {
        return "Person{" +
                "name='" + name + '\' ' +
                '} '; }}class Student extends Person{
    public Student(a){
        this.name="Students"; }}class Teacher extends Person{
    public Teacher(a){
        this.name="Teacher"; }}Copy the code

2.3 Class objects of all types

// All types of classes
public class Test04 {
public static void main(String[] args) {
    Class c1 = 0bject.class; / / class
    Class c2 = Comparable.class; / / interface
    Class c3 = String[].class; / / - dimensional array
    Class c4 = int[][] .class; // A two-dimensional array
    Class c5 = override.class; / / comment
    Class c6 = ElementType.class; / / the enumeration
    Class c7 = Integer .class; // Basic data type
    Class c8 = void.class; //void
    Class c9 = Class.class; //Class

    System.out.println(c1);
    System.out.println(C2) ;
    System.out.println(c3);
    System.out.println(c4);
    System.out.println(c5) ;
    System.out.println(c6) ;
    System.out.println(c7);
    System.out.println(c8) ;
    System.out.println(c9) ;
    // As long as the element type is the same as the dimension, it is the same Class.
    int[] a = new int[10];int[] b = new int [100]; System.out. println(a. getClass() .hashCode()); System. out. println(b. getClass() .hashCode()); }}Copy the code

Class loading and ClassLoader

3.1 JAVA Memory Analysis

When a program actively uses a class that has not been loaded into memory, the system initializes the class through the following three steps.

3.2 Understanding of class loading and ClassLoader

Loading: The process of loading the bytecode content of a class file into memory, converting this static data into a runtime data structure for the method area, and then generating a java.lang.class object representing this class.

Preparation: The stage of formally allocating memory for a class variable (static) and setting its default initial value, all of which will be allocated in the method area. Translation: A process whereby symbolic references (constant names) in the virtual machine’s constant pool are replaced with direct references (addresses).

Initial:

Implementation of a class constructor () method. The class constructor () method is generated by combining the assignment of all class variables in a class that are automatically collected at compile time with statements in a static code block. Class constructors build class information, not objects of that class. Preparation: When initializing a class, if it is found that its parent has not been initialized, the initialization of its parent needs to be triggered first. : : Virtual machine ensuring that a class’s < clinit>() methods are locked and synchronized correctly in a multi-threaded environment.

public class Test05 {
   public static void main(String[] args) {
      Aa=newA();
      System. out. println(A.m) ;
      /* 1. Load into memory, generate a class corresponding to the class object 2. Initialize 
      
       (){system.out.println (" Class A static code block initialization "); m =300; m = 100; } m =100 */
      }}class A{
      static {
      System. out. println("Class A static code block initialization"); m =300;
      }
      /* m = 300 m = 100 */
      static int m = 100; .
      public A(a) {
      System. out. println("Initialization of no-parameter constructs of class A"); }}Copy the code

Running results:

3.3 When does class initialization occur?

Passive reference of a class (class initialization must occur) Preparation of a class object, such as a class object, for which the parent of the class has not been initialized. Passive reference of its parent class is initialized. When accessing a static field, only the class that actually declares the field is initialized. Such as: If a static variable of a parent class is referred to by a subclass, no initialization of the subclass is triggered.

3.4 The role of class loaders

Primary implementation of class loading: loading the class file bytecode contents into memory, converting this static data into a method area runtime data structure, and then generating an object in the heap representing this class java.lang.class as an access point to the class data in the method area. Class cache: A standard JavaSE class loader can find classes on demand, but once a class is loaded into the class loader, it remains loaded (cached) for some time. However, the JVM garbage collection mechanism can reclaim these Class objects.

public class Test07 {
public static void main(String[] args) throws ClassNotFoundException {
        // Get the loader for the system class
        ClassLoader systemClassLoader = ClassLoader .getSystemClassLoader() ;
        Sys tem.out .println(sys temClassLoader) ;
        // Get the parent class loader of the system class loader -- > force display class loader
        ClassLoader parent = systemClassLoader . getParent() ;
        System. out . println(parent);
        // Get the parent class loader of the display class loader -- > root loader (C/ C ++)
        ClassLoader parent1 = parent. getParent() ;
        Sys tem. out . println(parent1) ;
        // Tests which loader is loading the current class
        ClassLoader classLoader = Classi. forName ("com. kuang. reflection.Test07") . getClassLoader();
        System. out . println(classLoader);
        classLoader = Class . forName ("java.lang. 0bject") . getClassLoader();
        System. out .pr intln(classLoader);
        // How to obtain the system class loader can load path
        System. out.pr intln(Sys tem. getProper ty("java. class.path"));
        // Parent delegate mechanism
        // java. lang. string-->}}Copy the code

Create an object for the runtime class

4.1 Get the complete structure of the runtime class

Get the complete structure of the runtime class Field, Method, Constructor, Superclass, Interface, Annotation via reflection

All interfaces implemented, all inherited parent classes, all constructors, all methods, all Field annotations

public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
      Class c1 = Class.forName("com. kuang. reflection.User");// Get the name of the class
      System.out.println(c1. getName()); // Get the package name + class name
      Sys tem.out.println(c1. getSimpleName()); // Get the class name
      
      // Get the class attributes
      System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
      Field[] fields = c1.getFields(); // Only the public attribute can be found
      fields = c1.getDeclaredFields(); // Find all attributes
      for (Field field : fields) {
      System.out.println(field);
      
      // Gets the value of the specified attribute
      Field name = c1.getDeclaredField( name: "name"); System.out.println(name);// Get the class method
      System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = =");
      Method[] methods = C1 . getMethods(); // Get all the public methods of this class and its parent
      for (Method method : methods){
      System.out.println("Normal :"+method);
      }
      methods = C1.getDeclaredMethods();// Get all the methods of this class
      for (Method method : methods) {
      System.out.println("getDeclaredMethods :"'+method) ; GetName = c1. getMethod("getName", null); Method setName = c1. getMethod("setName",String.class); System.out.println(getName); System.out.println(setName); / / get the constructor of the specified System. Out. The println (" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = "); Constructor [] constructors = C1.getConstructors() ; for (Constructor constructor : constructors) { System.out.println(constructor); } constructors = c1.getDeclaredConstructors() ; for (Constructor constructor : constructors) { System.out.println("#"+constructor) ; Constructor = c1. constructorp (String. Class,int. Class,int. Class); System.out. println(" specify :"+declaredConstructor); }}Copy the code

4.2 summary

In the actual operation, the operation code that gets the information about the class is not often developed. Be sure to familiarize yourself with the java.lang.Reflect package, the reflection mechanism. How to get properties, methods, constructor names, modifiers, etc.

4.2.1 What can I do with a Class object?

Create objects of the Class by calling newInstance() on the Class object

  1. A class must have a constructor with no arguments.
  2. The constructor of the class needs to have sufficient access.

4.2.2 thinking

Can’t you create an object without a constructor with no arguments? An operation can be instantiated only if the constructor in the class is explicitly called at operation time and the arguments are passed in.

The steps are as follows:

  1. GetDeclaredConstructor (Class… ParameterTypes gets the constructor of the specified parameter type for this class
  2. Pass an array of objects to the constructor parameters that contain the parameters required by the constructor.
  3. Instantiate objects by Constructor

4.3. Get the complete structure of the runtime class

// Create objects dynamically, by reflection
public class Test09 {
public static void main(String[] args) throwsClassNotFoundException, IllegalAccessException.{
      // Get the Class object
      Class C1 = Class.forName ("com.cy.reflection.User");
      // Construct an object
      //User user = (User)c1. newInstance(); // Call the class's no-argument constructor
      //System.out.println(user);
      
      // Create the object through the constructor
      //Constructor constructor = c1. getDeclaredConstructor (String.class, int.class, int.class) 
      //User user2 = (User)constructor. NewInstance (" qingfeng ", 001, 18);
      //System.out.println(user2);
      
      // Call normal methods through reflection
      User user3 = (User )c1.newInstance();
      // Get a method by reflection
      Method setName = c1. getDeclaredMethod("setName", String.class);

      / / invoke: activation
      //(object, "method value ")
      setName.invoke(user3,"The wind");
      System.out.println(user3.getName());

       // Manipulate attributes through reflection.
      System.out.println("= = = = = = = = = = = = = = = = ="); 
      User user4 =(User)c1.newrnstance();
      Field name = c1.getDeclaredField("name");

      // Private properties cannot be manipulated directly, we need to turn off the program's security monitoring, property or method setAccessible(true);
      name.setAccessible(true); / / true to shut down
      name.set(user4,"The wind 2"); System.out.println(user4.getName()) ; }}Copy the code
package com.cy.java.oop;

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

class Point{
    private int x;
    private int y;
    public Point(int x,int y){
        this.x=x;
        this.y=y;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getX(a) {
        return x;
    }

    public int getY(a) {
        return y;
    }

    @Override
    public String toString(a) {
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '} '; }}public class ReflectTests {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //1. Construct an instance object of type Point by reflectionClass<? > c1=Class.forName("com.cy.java.oop.Point");
        //1.2 Gets the class constructor object based on the bytecode objectConstructor<? > constructor=c1.getConstructor(int.class,int.class);
        Object o1=constructor.newInstance(10.20);
        System.out.println(o1);
        //2. Assign attributes directly to the point class instance via reflection
        Field f1 = c1.getDeclaredField("x");
        f1.setAccessible(true);// Set accessibility
        f1.set(o1, 1000);// Assign 1000 to the f1 property of the point object
        System.out.println(o1);
        //3. Call the instance method of the Point class via reflection to assign a value to the attribute
        Method setMethod = c1.getDeclaredMethod("setX".int.class);
        setMethod.invoke(o1, 2000);// Assign 2000 to the setMethod method of o1
        System.out.println(o1);
        //4. Call the get method of the point class via reflection to get the attribute value.
        Method getMethod = c1.getMethod("getX"); Object getResult = getMethod.invoke(o1); System.out.println(getResult); }}Copy the code

4.4 setAccessible

Method and Field and Constructor objects both have setAccessible() methods. SetAccessible Enables or disables access security checks. A value of true indicates that the reflected object should be used without Java language access checks.

Improved efficiency of reflection. If reflection must be used in code that needs to be called frequently, set this to true. The value of false indicates that the reflected object should perform Java language access checks.