Reflection mechanism in java
Catalog
1. The concept of reflection mechanism
2. Base Class of Reflection
3. Usage of reflection
4. Examples of applications of reflection
Author's introduction: A stack of learning notes, a person working hard
The concept of reflection mechanism:
In the run state, all the properties and methods of this class can be obtained for any class, and any method and properties (including private methods and properties) can be invoked for any object. This dynamically acquired information and the ability to dynamically invoke the methods of the object are called the reflection mechanism of the java language.Reflection is considered the key to dynamic language.Simply put, reflection is the mapping of various components of java to corresponding java classes.
As a general rule, reflections make this kind of thing completely transparent to us, and you can get anything you want.Includes construction methods, properties, and methods.
The java reflection mechanism provides:
Determine at run time which class any object belongs to;
Construct an object of any class at run time;
Determine at runtime which member variables and methods any class has;
Call the method of any object at run time;
Generate dynamic proxy.
In fact, it also involves the dynamic and static of language. The java language itself is not a dynamic language, but it has a very prominent dynamic mechanism, which is what we call reflection mechanism.
What is dynamic language?That is, while the program is running (note that it is running, not compiling), it allows you to change the program structure or variable type.Static, on the other hand, has no such features.
Reflected Base Class Class
Class classes are the basis for reflection implementations, so to learn reflection, you must first understand some basic concepts of Class classes.
What is a class?Classes are instance objects of Class classes, so Class classes are classes of all classes.
To dissect a class, you must first obtain the byte code file object for that class.Anatomy uses methods in the Class class, so first get the Class object for each byte code file.
Class classes do not have a common construction method. Class objects are automatically constructed by the Java virtual machine when the class is loaded and by calling the defineClass method in the class loader, so a Class object cannot be explicitly declared.There's one more thing involved here, loading classes
A brief explanation:
Class Loader: When a program needs to use a class, if the class has not been loaded into memory, the system will initialize the class by loading, connecting, and initializing the three steps
Loading: This means reading a class file into memory (the compiled file is a.Class file) and creating a Class object for it
When any class is used, a Class object is created, and the first time, the second time, the existence of the class is determined.
Connection: Verify that the correct internal structure exists and is in harmony with other classes
Prepare to allocate memory for static members of the class and set default initialization values
And do a parse: replace the character references in the binary data of the class with direct references.
As mentioned above, Class objects cannot be created directly, but we can get Class classes in other ways. There are currently three ways to get the Class classes we want, and after getting the Class classes, we can use reflection normally.
There are three ways to get a Class (to get a byte code object for a class):
First: using object acquisition, using object's getClass acquisition
Person person = new Person(); Class clazz = person.getClass();
Second, use the static attribute class
Class clazz = Person.class
Third, use the static method forName of the Class class (the class name of the string)
Note; the class name is written in full package name
Class clazz = Calss.forName(".......");
Okay, here's the point. It's fun how reflection works!
Usage of reflection
What can you get from reflection above for any class? Let's see if this is true.
What is the first step?Of course, there are three ways to get this optional Class class.There are three ways, let's start with an example.
Upper Code
//Get Class First Method Student student = new Student(); Class clazz = student.getClass(); //Get Class Second Method Class clazzTwo = Student.class; //Get Class Third Method Class clazzThree = Class.forName("demo.qzxxbj.entity.Student"); System.out.println("First"+clazz+"\n The second"+clazzTwo+"\n Third"+clazzThree);
Result
First class demo.qzxxbj.entity.Student Second class demo.qzxxbj.entity.Student Third class demo.qzxxbj.entity.Student
You can see that the Class objects from the three methods are the same, no difference.
The third way is to throw an exception that cannot find the class.
Student is a simple class and can be any class.
Get the properties of any class through Class
Code for Student class
package demo.qzxxbj.entity; /** * @author WeChat Public Number: Full Stack of Learning Notes * @date 2020/3/29 * @description */ public class Student { private String name; private Integer age; private String sex; public int number; public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }
}
The following methods for getting a Class are the second, simpler
//Get Class Second Method Class clazzTwo = Student.class; //Gets the public member variable for the specified property name of the class, including the parent's Field field = clazzTwo.getField("number"); //field public int demo.qzxxbj.entity.Student.number System.out.println("The class specifies the property name public Member variables, including parent's"+field); //Gets the variable declared by the specified name of the class, i.e. excluding the parent class Field deField = clazzTwo.getDeclaredField("name"); // deField private java.lang.String demo.qzxxbj.entity.Student.name System.out.println("All declared variables of this class, i.e. those excluding the parent class"+deField); //Gets the member variables of all public declarations of this class Field fields[] = clazzTwo.getFields(); System.out.println("public Declared variable:"); //public int demo.qzxxbj.entity.Student.number for (Field field1:fields){ System.out.println(field1); } //Gets all member variables of the object Field deFields[] = clazzTwo.getDeclaredFields(); System.out.println("All member variables of the object"); //private java.lang.String demo.qzxxbj.entity.Student.name //private java.lang.Integer demo.qzxxbj.entity.Student.age //private java.lang.String demo.qzxxbj.entity.Student.sex //public int demo.qzxxbj.entity.Student.number for (Field field1:deFields){ System.out.println(field1); }
Remember the differences between getFields (), getField (String name), getDeclaredFields (), and getDeclaredField (String name), and you will be able to master this point!
Get any member method from Class
Let's see the code.
Get Member Method
//Get Class Second Method Class clazzTwo = Student.class; //Depending on the method name and parameter type, only methods declared by the public, including those of the parent class, can be obtained Method method = clazzTwo.getMethod("setAge",Integer.class); //public java.lang.Integer demo.qzxxbj.entity.Student.getAge() System.out.println(method); //Gets all the property methods declared by this class based on the method name and parameter name, excluding those of the parent class Method deMethod = clazzTwo.getDeclaredMethod("setAge", Integer.class); System.out.println(deMethod); //Gets all public methods declared by the object, including the parent's Method methods[] = clazzTwo.getMethods(); //Gets all methods declared by the object, but does not contain methods of the parent class Method deMethods[] = clazzTwo.getDeclaredMethods();
What does a Method print out?The code above also contains
public void demo.qzxxbj.entity.Student.setAge(java.lang.Integer)
Is it very similar to the Field we talked about earlier?
Now that we are talking about methods, there must be method calls involved. We have these methods, and how do we call the methods in this class?With invoke functions, Method contains an invoke function in this class. As you know, if you are good at English, this invoke means "call" in Chinese.
How to use it?
//Get Class Second Method Class clazzTwo = Student.class; //Depending on the method name and parameter type, only methods declared by the public, including those of the parent class, can be obtained Method method = clazzTwo.getMethod("setAge",Integer.class); //public java.lang.Integer demo.qzxxbj.entity.Student.getAge() System.out.println(method); //Create an instance of an object with Class Student student = (Student) clazzTwo.newInstance(); //function call Object value = method.invoke(student,20); //null System.out.println(value);
You may not understand the above code. Let me tell you a little. First, we get a Class of a class, then we get a setAge method of that class through this Class, get this method, and then continue to call this method. Should the method be called inside an instance object?So we need to instantiate an object first, and by what means, create an instance through newInstance() inside the class, which requires that the instantiated class have a parameterless construction method.There are other ways to create an instance, as we will say later.Once we've created an instance object, we can start calling the method.
The invoke calls the method, and the first argument to invoke is an instantiated object, otherwise where do I find the method?The second parameter, or the third parameter, and so on, all subsequent parameters are those of the method that I call, which I fill in in order to OK.Then this function returns an Object object, you can think, I call a method is not to let him do something, do these things need to return a thing, do not know what this thing is, just use Object to get it.Since the method we call does not need a return value, it is null.It's easy, isn't it?I learned to remember to give me some attention!The beautiful text is put into your hands for the first time.
Get construction methods from Class
I put this in the last place to learn, after all, I think the proportion used is relatively small.Let's learn how to use Class to get a construction method and call it.
public Student(String name, int id) { this.name = name; this.id = id; }
Here we add a constructor to the Student class.
Then let's get this construction method.
//Get Class Second Method Class clazzTwo = Student.class; //Getting a parameterless construct, declared by the public, including the parent class, plus parameters is to get a specific construct Constructor constructor = clazzTwo.getConstructor(); //public demo.qzxxbj.entity.Student() System.out.println(constructor); //Get the construction method for all public declarations of this class Constructor constructors[] = clazzTwo.getConstructors(); //Gets the construction method of the specified parameter Constructor deConstructor = clazzTwo.getDeclaredConstructor(String.class,Integer.class); //Gets all constructors of this class, excluding parent's Constructor deConstructors[] =clazzTwo.getDeclaredConstructors();
The code above should be easy to read, I won't go into details.Now let's talk about how to use the resulting construction method, which, as its name implies, instantiates an object. So let's also talk about how to instantiate an object with a Class. Now let's instantiate an object with a constructor method
Student student = (Student) deConstructor.newInstance("Full stack of learning notes",21); //21 System.out.println(student.getAge());
Now you know, we almost finished the function of reflection, just like a dynamic proxy of reflection. This is more important, a blog will be dedicated, the code is not easy.Hope to get a little attention.WeChat Public Number: Learn notes from the whole stack, and push beautiful messages for you every day.
Finally, I wrote a java reflective sql statement stitching based on my previous experience, which is equivalent to a reflective application.
Example application of reflection
Is it also a bit dazzling to reflect the dynamic generation of SQL statements?
Go directly to the code, I only send a single SQL statement, you can trust me to get the complete code if you are interested!
public String insert(Object object) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {` //insert into student(id,name,sex) values (1, "full stack of study notes", "man") StringBuilder sql = new StringBuilder(); Class clazz = object.getClass(); sql.append("insert into "); sql.append(clazz.getSimpleName()+"("); Field[] fields = clazz.getDeclaredFields(); for(Field field:fields){ sql.append(field.getName()+","); } sql.deleteCharAt(sql.length()-1); sql.append(")"); sql.append(" values ("); for(Field field:fields){ field.setAccessible(true); Object value = field.get(object); String fieldName = field.getName(); String str1 = fieldName.substring(0,1).toUpperCase(); String str2 = fieldName.substring(1,fieldName.length()); String strValue = str1.concat(str2); //String strValue = fieldName.substring(0,1).toUpperCase().concat(fieldName.substring(1,fieldName.length())); Method method = clazz.getMethod("get"+strValue,null); Object value1 = method.invoke(object,null); // if(value1.getClass().equals(String.class)) // if(field.getType().equals(String.class)) if(value1 instanceof String){ sql.append("\"").append(value1).append("\"").append(","); }else { sql.append(value1).append(","); } } sql.deleteCharAt(sql.length()-1); sql.append(")"); System.out.println(sql.toString()); return sql.toString(); }
This is the end of the explanation. There should also be an article about notes later. If you find something wrong in the article, please point it out.If you think you can learn a lot, please pay attention!Welcome to Forward!Let more friends learn!
WeChat Public Number: The Public Number is getting better every day, and the wonderful American Language is being pushed every day