directory

1. The concept of reflection

1, concept,

2. How to get the bytecode file object

2.1 Concepts of metadata

2.2 Method of obtaining class Objects

3. How does reflection get metadata and access it

1. Access rights

2. Acquisition method

2.1 Accessing static methods

2.2 Accessing class methods

3. Get the field and read the value of the field

4. Get the implementation interface

5. Get the constructor and create the instance

Get the inherited parent class

7. Get annotations

4. Reflection examples

5, summary


Reflection is an advanced concept in Java, usually in the second half of the book. Reflection is also a necessary skill to write a framework. Reflection is very important. I still remember that I did not understand what reflection is in the first two years after graduation. Let’s talk about reflection today. I hope this article can help you solve the same puzzle. Without further ado, let’s get started.

1. The concept of reflection

1, concept,

Reflection refers to the running state, for any class, can know all the properties and methods of the class, for any object, can call any method. This ability to dynamically retrieve information and invoke object methods is called the Reflection mechanism of the Java language. Reflection is powerful, with advantages and disadvantages.

Advantages: High flexibility. Because reflection is dynamically compiled, that is, object instances are created and fetched dynamically only at run time.

Disadvantages: Low execution efficiency.

2. How to get the bytecode file object

2.1 Concepts of metadata

Metadata: Metadata is the code data used to describe a class. All class files loaded into the virtual machine are constructed into class objects. Class objects describe what a class has, including well-known implemented interfaces, inherited abstract classes, member variables, class variables, member methods, class methods, static methods, etc. This class object is metadata.

  • Class: Represents a Class.
  • Field class: Represents the member variables of the class (also known as attributes of the class).
  • Method class: A Method that represents a class.
  • Constructor class: represents the Constructor of a class.

 

 

2.2 Method of obtaining class Objects

  • 2.2.1 By object, because any object must be associated with a class object

  • 2.2.2 Directly obtained from class objects

  • 2.2.3 Through the class loader, because the class loader reads the class file and returns a class object

    Object to be used for reflection (a random object defined just for demonstration purposes)

    package org.pdool.reflect;
    
    / * * *@authorParsley * /
    public class Npc {
      / / a static field
      public static int NPC_TYPE_1 = 1;
      // Private member variables
      private int npcType;
      // Share member variables
      public String name;
      // No argument constructor
      public Npc(a) {}// Has a parameter constructor
      public Npc(int npcType, String name) {
          this.npcType = npcType;
          this.name = name;
      }
    
      public int getNpcType(a) {
          return npcType;
      }
    
      public void setNpcType(int npcType) {
          this.npcType = npcType;
      }
    
      public String getName(a) {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
      // Static method
      public static void sayHello(String word){
          System.out.println("hello "+ word); }}Copy the code

    Three ways to get a reflection class

    package org.pdool.reflect;
    
    / * * *@authorParsley * /
    public class ClazzTest {
       public static void main(String[] args) {
           // The first way to get a Class object
           Npc npc1 = new Npc();// This new generates an Npc object, a Class object.
           Class npcClazz1 = npc1.getClass();// Get the Class object
           System.out.println(npcClazz1.getName());
    
           // The second way to get a Class object
           Class npcClazz2 = Npc.class;
           System.out.println(npcClazz1 == npcClazz2);// Check whether the Class object obtained in the first way is the same as the Class object obtained in the second way
    
           // The third way to get a Class object
           try {
               Class npcClazz3 = Class.forName("org.pdool.reflect.Npc");// Note that this string must be the real path, i.e. the classpath with the package name, package name. The name of the class
               System.out.println(npcClazz3 == npcClazz2);// Check whether the three methods get the same Class object
          } catch(ClassNotFoundException e) { e.printStackTrace(); }}}Copy the code

     

3. How does reflection get metadata and access it

1. Access rights

The default behavior of reflection is limited by Java’s access controls, which can be bypassed by setAccessible.

// Sets the object array accessible flag
static void setAccessible(AccessibleObject[] array, boolean flag)  
Copy the code

2. Acquisition method

2.1 Accessing static methods

public static void main(String[] args) throws NoSuchMethodException,InvocationTargetException, IllegalAccessException {
       Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
       Class npcClazz = Npc.class;
       // The first argument is the name of the method, and the second argument is the class object of the function
       Method sayHello = npcClazz.getMethod("sayHello", String.class);
       sayHello.invoke(npc, "world");
  }
Copy the code

2.2 Accessing class methods

      Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
      System.out.println(npc.getName());
      Class npcClazz = Npc.class;
      // The first argument is the name of the method, and the second argument is the class object of the function
      Method sayHello = npcClazz.getMethod("setName", String.class);
      sayHello.invoke(npc, "world");
      System.out.println(npc.getName());
Copy the code

3. Get the field and read the value of the field

       Npc npc = new Npc(1."The Demon God and the Female Phoenix.");
       Class npcClazz = Npc.class;
       // Get the field and set it accessible
       Field field = npcClazz.getField("name");
       field.setAccessible(true);
       System.out.println( field.get(npc));
Copy the code

4. Get the implementation interface

5. Get the constructor and create the instance

 

    Class npcClazz = Npc.class;
               Constructor declaredConstructor = npcClazz.getDeclaredConstructor(int.class,String.class);
       Npc npc = (Npc) declaredConstructor.newInstance(1."Demon god");
       System.out.println(npc.getName());
Copy the code

Get the inherited parent class

      Class npcClazz = Npc.class;
      Class superclass = npcClazz.getSuperclass();
      System.out.println(superclass.getName());
Copy the code

 

7. Get annotations

Class npcClazz = Npc.class;
       Annotation[] annotations = npcClazz.getAnnotations();
// Runtime annotations
       for (Annotation annotation : annotations) {
           System.out.println(annotation.getClass().getName());
      }
Copy the code

4. Reflection examples

It’s not the end goal to get the metadata, it’s the end goal to call the class at run time. For example, we all know how to implement IOC in Spring.

Process:

1. Spring reads the path of the bean configured in XML at project startup time.

2, then read the Class into the classloader through class.forname.

3. Then create all bean instances by reflection and store them in the container.

4. The bean object can be obtained directly in the project.

Let’s do this roughly, because XML is a bit of a chore to read, so we’ll use property instead. You can just experience the idea.

package org.pdool.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/ * * *@authorParsley * /
public class ClazzTest {
  public static void main(String[] args){
      try {
          Map<String,Object> container = new HashMap<>();
          1. Read the configuration
          InputStream in = ClazzTest.class.getResourceAsStream("/beans.properties");
          Properties property = new Properties();
          property.load(in);
          //2. Reflection creates objects
          Set<Object> keySet = property.keySet();
          for (Object key : keySet) {
              // 2.1 Get the full path of the class
              String classStr = (String) property.get(key);
              // 2.2 Loading a class to a VMClass<? > beanClazz = Class.forName(classStr);// 2.3 Get the default constructorConstructor<? > declaredConstructor = beanClazz.getDeclaredConstructor();// 2.4 Creating an instance
              Object o = declaredConstructor.newInstance();
              container.put((String) key,o);
          }
          // 3. Obtain an instance
          Npc npc = (Npc) container.get("npc");
          System.out.println(npc == null);
      } catch(Exception e) { e.printStackTrace(); }}}Copy the code

5, summary

When using Java reflection, the main steps include:

  1. Gets the Class object of the target type

  2. Get a Constructor object, a Method object, or a Field object from a Class object

  3. The Constructor object, Method object and Field object are used to obtain the specific information of the Constructor, Method and attribute of the class, and the subsequent operations.

    If you have any questions, you can leave a message and we can discuss it together. If you have no questions, you can leave a message and we can make friends

Typing is not easy, like, forward, pay attention to three even, thank you, by the way, pay attention to my public number: [cilantro chat game] there are more welfare oh