1. The reflection

A dynamic language allows you to change program structure or variable types while a program is running. Like Python,Ruby is a dynamic language. Java is obviously not a dynamic language, but Java has one very prominent dynamic correlation mechanism :Reflection.

Reflection definition: The Java reflection mechanism is to know all the properties and methods of any class in the running state; For any object, you can call any of its methods and properties; This ability to dynamically retrieve information and invoke methods on objects is called the Reflection mechanism of the Java language

Normally, when we use a class, we get a class and then instantiate it. But with reflection we can get information about a class from an object.

Java’s reflection mechanism enables:

  1. Determine the class of any object at run time;
  2. Construct an object of any class at runtime;
  3. Determine which member variables and methods any class has at run time.
  4. Call a method of any object at runtime;
  5. Generating dynamic proxies

2. Access to the Class

The first thing to do with reflection is get the Class object. The Class object is the source of reflection.

When a Class is loaded, the Java VIRTUAL machine automatically generates a Class object. Each Class generates only one Class object. The Class object holds all the contents of the Class, such as member properties, member methods, and constructors.

1. The method to get the Class object

  1. Object. GetClass ()
  2. The name of the class. The class
  3. Class. Forname (” package name + Class name “)

Example 1:

public class Demo1 { public static void main(String[] args) throws ClassNotFoundException { // 1. Class class <String> cls1 = string.class; System.out.println(cls1); // 2. Object. GetClass () Class<? Extends String> cls2 = "ha ".getClass(); System.out.println(cls2); // 3.Class. ForName (" package name + Class name ") Class<? > cls3 = Class.forName("java.lang.Object"); System.out.println(cls3); // Depending on the type of package. Cls7 = integer.type; cls7 = integer.type; System.out.println(cls7); Class cls5 = int.class; System.out.println(cls5); }}Copy the code

There are three ways to use reflection, mainly the third way. The first way is that we already have objects, so it doesn’t make much sense to use reflection. The second need to guide package, do not guide package compilation will not pass, too strong dependence. So we mainly use the third option, we can either pass in the string directly or we can write the string in the configuration file.

3. Get the constructor by reflection

Let’s start by defining a Person class:

public class Person { private String name; private int age; private String id; Public Person() {system.out.println (" I am an empty argument construct "); } private Person(String id) { this.id = id; System.out.println(" I am a private single-argument construct "); } public Person(String name, int age, String id) { this.name = name; this.age = age; this.id = id; System.out.println(" I am a public three-argument construct "); } 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 String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "[name=" + name + ", age=" + age + ", id=" + id + "]"; }}Copy the code

1. Get the constructor

The constructor of a class can be retrieved by reflection

Example 2:

public class Simple { public static void main(String[] args) throws NoSuchMethodException, Class<Person> cla = person.class; GetConstructors () gets an array of Constructor objects for such public constructors, Constructor<Person>[] con = (Constructor<Person>[]) cla.getConstructors(); System.out.println(Arrays.toString(con)); Constructor<Person> con1 = cla.getconstructor (string.class, Constructor<Person> con1 = cla.getconstructor (String. int.class, String.class); System.out.println(con1); Constructor<Person>[] con2 = (Constructor<Person>[]); // Use getDeclaredConstructors() to get an array of Constructor objects for all declared constructors of this class.  cla.getDeclaredConstructors(); System.out.println(Arrays.toString(con2)); // Return a Constructor object using the getDeclaredConstructor() method, The object reflects the Class / / object represented by the Class or interface specifies the method to construct the Constructor < Person > con3 = cla. GetDeclaredConstructor (String. Class); System.out.println(con3); }}Copy the code

Program running results:

    [public com.shy.test.Person(java.lang.String,int,java.lang.String), public com.shy.test.Person()]
    public com.shy.test.Person(java.lang.String,int,java.lang.String)
    [public com.shy.test.Person(java.lang.String,int,java.lang.String), private com.shy.test.Person(java.lang.String), public com.shy.test.Person()]
    private com.shy.test.Person(java.lang.String)
Copy the code

2. Create objects from the constructor obtained by reflection

Example 3:

import java.lang.reflect.Constructor; import java.util.Arrays; Public class Simple {public static void main(String[] args) throws Exception {// Obtain the class object of the Person class class <Person> clA =  Person.class; Use getDeclaredConstructors() to get an array of Constructor objects for all declared constructors of this class. Constructor<Person>[] con = (Constructor<Person>[]) cla.getDeclaredConstructors(); System.out.println(Arrays.toString(con)); // Create object Person P1 =con[0]. NewInstance (" Zhangsan ",22,"1997123"); Con [1].setaccessibletrue (true); // Open the constructor, because the constructor represented by con[1] is private and cannot be used directly. Person p2=con[1].newInstance("2019116"); con[1].setAccessible(false); }}Copy the code

Program running results:

[public com.shy.test.Person(java.lang.String,int,java.lang.String), private com.shy.test.Person(java.lang.String), Public com.shy.test.person ()] I'm a public three-parameter construct I'm a private one-parameter constructCopy the code

4. Get member variables by reflection and use them

1. Batch

  • 1).field [] getFields(): getFields()Copy the code
  • 2).Field[] getDeclaredFields(): getDeclaredFields();Copy the code
  • 2. Get a single:
  • 1). Public Field getField(String fieldName);Copy the code
  • Public Field getDeclaredField(String fieldName)Copy the code

Example 4:

import java.lang.reflect.Field; Public class Simple {public static void main(String[] args) throws Exception {// Obtain the class object of the Person class class <Person> clA =  Person.class; System. / / access field out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- to get all of the property (including private, protected, the default) -- -- -- -- -- -- -- -- -- -- -- -- -- "); Field[]fields=cla.getDeclaredFields(); for(Field f:fields){ System.out.println(f); } System. Out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get properties and call -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - "); F =cla.getDeclaredField("name"); f=cla.getDeclaredField("name"); System.out.println(f); Person p= cla.getconstructor ().newinstance (); F.setaccessible (true); /* Set (Object obj,Object value) * obj: the Object of the field to be set * value: the value of the field to be set */ f set(p,"zhangsan"); System.out.println(p); }}Copy the code

Program running results:

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- to get all of the property (including private, protected, the default) -- -- -- -- -- -- -- -- -- -- -- -- -- private Java lang. String com. Shy. Test. The Person. The name private int com.shy.test.Person.age private java.lang.String com.shy.test.Person.id -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- get properties and call -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - private Java. Lang. String com. Shy. Test. The Person. The name is empty and I structure [name=zhangsan, age=0, id=null]Copy the code