[Java Interview Guide] Reflection (1) Introduction to Reflection

If you are asked: what is reflection? Why do you need reflection, and the application of reflection? How would you answer that?
This article will introduce you to reflection, understand the concept and basic application of reflection. The principle of reflection and the in-depth exploration of the source code will be introduced in the next few articles.

1. What is reflection?

To understand what reflection is, let's first look at what is "orthophoto". A common way to obtain a student's orthophoto is as follows:

Student student = new Student();

Usually we declare directly, or new Student()directly , and then use it. And a reflection example is as follows:

// 这里的“com.demo.Student”是需要反射的类的全限定名(包名+类名)
Class clz = Class.forName("com.demo.Student")	
Object stu = clz.newInstance();

Get the Class class of the instance first, and then generate a Student Instance through its Class class. The above two methods (new Student and clz.newInstance) are equivalent in effect, and both obtain an instance of Student.

So what is reflection? Reflection is an important feature in Java. Using reflection, you can dynamically generate objects, obtain object properties, and call object methods at runtime.
Oracle's official explanation for reflection is:

Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.
The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

The core of reflection is that the JVM dynamically loads classes or calls methods/access properties at runtime, and it does not need to know who the running object is in advance (when writing code or during compilation).

The problem of reflection:
Here is a brief mention: reflection is equivalent to a series of interpretation operations, informing the JVM of what to do, and its performance is much slower than that of direct Java code.

Second, why do you need reflection?

To give an intuitive example (just to illustrate one usage):
If I ask you to write a printout based on the name entered at runtime, you will write code similar to the following:

public void sayHello(String name) {
    
    
    // 在运行前根本不知道 name 是什么,只有在运行时 name 才会被确认并打印出来
    System.out.println("hello, " + name);
}

Then in the same way, you may not know what class to use when writing the code, and you will only know it at runtime. For example, when loading a database driver, you can directly new out the specific driver class, but if you change the database, do you need to modify the source code and repackage and update it?

new com.mysql.jdbc.Driver();

Then you might say, I just need to write a few more if elses, like this:

if ( xxx == "mysql") {
    
    
    new com.mysql.jdbc.Driver();
else if ( xxx == "redis" ) {
    
    
    new com.redis.jdbc.Driver();
else if ( ... ){
    
    
}

The problem with this is that all the jdbc connection libraries must be collected during the compilation period, regardless of whether they are used or not, they will be loaded into the memory, and there will be a huge waste if there are too many database types.
Then this situation can be solved by reflection, and the corresponding class is dynamically loaded at runtime. You can also specify which database class to use in the configuration file, and you can use this program to connect to different databases.

// 反射的方式动态加载类
Class.forName("com.mysql.jdbc.Driver");

Third, the basic use of reflection

Here's what you can do with reflection:

1) Get the Class object

// 1 使用 Class 类的 forName 静态方法
 Class.forName(driver);

// 2 直接获取某一个对象的 class
Class<?> cl = int.class;

// 3 调用某个对象的 getClass() 方法
StringBuilder str = new StringBuilder("123");
Class<?> klass = str.getClass();

2) Determine whether it is an instance of a certain class

public static void displayObjectClass(Object o) {
    
    
    if (o instanceof Vector)
   		System.out.println("对象是 java.util.Vector 类的实例");
  	else if (o instanceof ArrayList)
   		System.out.println("对象是 java.util.ArrayList 类的实例");
   	else
   		System.out.println("对象是 " + o.getClass() + " 类的实例");
}

3) Create an instance

Class<?> c = String.class;
Object str = c.newInstance();

4) Obtaining method

getDeclaredMethods()methods returns all methods declared by the class or interface, including public, protected, default (package) access, and private methods, but not inherited methods.
getMethods()Method returns all public methods of a class, including public methods of its inherited classes.
getMethod()The method returns a specific method, where the first parameter is the method name, and the following parameters are the objects of the Class corresponding to the parameters of the method.

public class ReflectDemo {
    
    
	public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    
    
	    Class<?> c = MyClass.class;

	    Method[] methods = c.getMethods();
	    Method[] declaredMethods = c.getDeclaredMethods();
	    Method method = c.getMethod("add", int.class, int.class);

        System.out.println("getMethods获取的方法:");
        for(Method m:methods)
            System.out.println(m);

        System.out.println("getDeclaredMethods获取的方法:");
        for(Method m:declaredMethods)
            System.out.println(m);
    }
}

class MyClass {
    
    
    public int add(int a, int b) {
    
    
        return a + b;
    }
    public int sub(int a, int b) {
    
    
        return a - b;
    }
}

// 输出
/*
getMethods获取的方法:
public int com.shuofxz.basic.ReflectDemo$MyClass.add(int,int)
public int com.shuofxz.basic.ReflectDemo$MyClass.sub(int,int)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

getDeclaredMethods获取的方法:
public int com.shuofxz.basic.ReflectDemo$MyClass.add(int,int)
public int com.shuofxz.basic.ReflectDemo$MyClass.sub(int,int)
*/

5) Call method

When we get a method from a class, we can use it invoke()to call this method.

public class ReflectDemo {
    
    
	public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    
    
        Class<?> mc = MyClass.class;
        Object obj = mc.newInstance();
        //获取methodClass类的add方法
        Method method = mc.getMethod("add", int.class, int.class);
        //调用method对应的方法 => add(1,4)
        Object result = method.invoke(obj, 1, 4);
        System.out.println(result);
    }
}

6) Obtain the member variable (field) information of the constructor and class

  • Get an instance of the Constructor class through the getConstructor method of the Class class
  • getFiled: access public member variables
  • getDeclaredField: All declared member variables, but cannot get the member variables of its parent class

Four. Summary

This article provides a preliminary introduction to the reflection mechanism. Let everyone understand what reflection is, why there is a function of reflection, and some basic usage methods. Subsequent articles will further explain the mechanism and principle of reflection.

Guess you like

Origin blog.csdn.net/shuofxz/article/details/128367512