This is the 26th day of my participation in the August Text Challenge.More challenges in August

reflection

Java reflection is an important feature of the Java language. Before learning about Java reflection, you should understand two concepts, compile time and run time.

Compile time: The process of giving source code to a compiler to compile into a file that the computer can execute. In Java, this is the process of writing Java code into a class file. Compile-time just does some translation. Instead of running the code in memory, it just manipulates the code as text, such as checking for errors.

Run time: is the compiled file to the computer to execute, until the end of the program. Runtime is the execution of code on disk in memory.

Java reflection mechanism

The Java reflection mechanism allows you 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 object methods is called the Reflection mechanism of the Java language. In simple terms, reflection refers to the ability of a program to retrieve information about itself at runtime. In Java, given the name of a class, all information about the class can be obtained through reflection.

Java reflection is widely used in server programs and middleware programs. On the server side, it is often necessary to dynamically invoke a specific method of an object based on a client’s request. In addition, in the implementation of ORM middleware, all properties of any JavaBean can be read or assigned values using Java reflection.

The Java reflection mechanism mainly provides the following functionality, which is located in the java.lang.Reflect package.

  • Determine the class to which any object belongs at run time.
  • Constructs an object of any class at run time.
  • Determine which member variables and methods any class has at run time.
  • Call a method of any object at run time.
  • Generate dynamic proxies.

To know the properties and methods of a class, you must first get the bytecode file object for that class. When you get information about a Class, you use the methods in the Class Class. So first get the object of class type corresponding to each bytecode file (.class).

1. The Class object

Before you can examine information about a Class, you first need to get the Class object. All types in Java include primitive types (int, Long, float, and so on), and even arrays have objects of Class Class associated with them. If you know the name of a Class at compile time, you can use the following method to get a Class object.

The.class file is now loaded into memory by the class loader, and the JVM creates the corresponding class object from its byte array. So, let’s look at Class objects.

A Class object is an instance of a Class Class, and we’ll walk through the structure of the Class Class step by step in this section.

But before I look at the source code, I’d like to ask the smart ones: If you were the JDK source code designer, how would you design the Class Class?

Suppose you now have a BaseDto class

The above class contains at least the following information (in order) :

  • Permission modifier
  • The name of the class
  • Parameterized types (generic information)
  • interface
  • annotations
  • Fields (emphasis)
  • Constructor (emphasis)
  • Methods (key points)

Eventually this information will be represented as 0101 in the.class file:

The entire.class file ends up as an array of bytes [] B, whose constructors, methods, and other “components” are actually bytes.

2. The constructor

We can get an instance of the Constructor Class via the Class object:

Class aClass = ... Constructor[] constructors = aclass.getconstructors ();Copy the code

The returned Constructor array contains each Constructor declared Public. If you know the type of the constructor argument you want to access, you can use the following method to get the specified constructor. This example returns a String constructor argument:

Class aClass = ... Constructor = aclass.getconstructor (new Class[]{string.class});Copy the code

Method 3.

The Method object can be obtained from the Class object as shown in the following example:

Class aClass = ... [] methods = aclass.getmethods ();Copy the code

The returned Method object array contains the collection of all variables declared public in the specified class.

If you know the argument type of the method you want to call, you can get the specified method directly from the argument type. In this example, the return method object name is “doSomething”, and its method argument is of type String:

Class aClass = ... Method = aclass.getMethod ("doSomething", new Class[]{string.class});Copy the code

If a method cannot be matched based on the given method name and parameter type, a NoSuchMethodException is thrown.

Reflection practical application

After the introduction of the principle of reflection above, it is time to start the application of reflection in the real scene, all the technology, you know the application of the technology is always the most valuable. The more you know, the better. The more you know, the more ideas you have.

Reflection of the actual scene of the application, here are mainly listed in these aspects:

  1. A dynamic proxy
  2. JDBC database connection
  3. Use of the Spring framework

Dynamic proxy is actually the use of reflection technology to achieve, in the program run to create a proxy class, used to proxy a given interface, dynamic processing of its proxy method call.

There are several steps to implement dynamic proxy:

  1. implementationInvocationHandlerInterface, overrideinvokeMethod that implements the logic called by the methods of the proxy object.
  2. Proxy.getProxyClassGetting proxy classes
  3. Method is executed, and the proxy succeeds

DynamicProxyHandler class InvocationHandler:

public class DynamicProxyHandler implements InvocationHandler { private Object targetObj; public DynamicProxyHandler() { super(); } public DynamicProxyHandler(Object targetObj) { super(); this.targetObj= targetObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {system.err. Println (" start executing targetObj method "); // Invoke method.invoke(targetObj, args); System.out.println(" end of execution method "); return null; }}Copy the code

Then execute proxy. newProxyInstance method to create Proxy object, and finally execute Proxy object method, code implementation is as follows:

User user = new UserImpl(); DynamicProxyHandler dynamicProxy = new DynamicProxyHandler(user); // First argument: classloader; The second argument: user.getClass().getinterfaces () : the interface of the proxied object; The third parameter: Proxy object User userProxy = (User) proxy.newProxyInstance (user.getClass().getClassLoader(), user.getClass().getinterfaces (), dynamicProxy); userProxy.login(); userProxy.logout();Copy the code

The above implementation is the JDK dynamic proxy, there is a dynamic proxy is Cglib dynamic proxy, Cglib dynamic proxy is widely used, such as Spring AOP framework, the implementation of method interception function.