What is reflection?

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.

Simply put, reflection is the mapping of various components of a Java class to Individual Java objects.

After we understand the basic concept of reflection, it is natural to ask the question, what is reflection good for?

Suppose there are two programmers. One programmer needs to use a class written by the second programmer when writing a program, but the second programmer does not complete the class he wrote. The first programmer’s code will not compile. At this point, Java reflection allows the first programmer to compile his own code without getting the classes written by the second programmer.

It knows the basic structure of a class, and this ability to explore the structure of a Java class is called “self-examination” of Java classes. For example, a class has: member variables, methods, constructors, packages and other information, using reflection technology can be dissected on a class, mapping each component into a single object. In Java, everything is an object, and reflection is a manifestation of object-oriented thinking.

With all that said, it still feels like fog and fog. So let’s start show code.

First let’s create a Robot class.

public class Robot {
    private String name;


    public void sayHi(String helloSentence) {
        System.out.println(helloSentence + "" + name);
    }


    private String throwHello(String tag) {
        return "Hello "+ tag; }}Copy the code

As the code shows, we define a private member variable and two methods.

And then we get it by reflection.

public class ReflectSample {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {

        Class rc = Class.forName("com.interview.javabasic.reflect.Robot");
        Robot r = (Robot) rc.newInstance();
        System.out.println("Class name is " + rc.getName());
        Method getHello = rc.getDeclaredMethod("throwHello", String.class);
        getHello.setAccessible(true);
        Object str = getHello.invoke(r, "Bob");
        System.out.println("getHello result is " + str);
        Method sayHi = rc.getMethod("sayHi", String.class);
        sayHi.invoke(r, "Welcome");
        Field name = rc.getDeclaredField("name");
        name.setAccessible(true);
        name.set(r, "Alice");
        sayHi.invoke(r, "Welcome"); }}Copy the code

First we create a Class object rc and assign it a value using the forName method. Here I would like to ask you a small question, loadClass and forName difference, you can think about it, the answer will be given at the end of the article.

Following our example, we create an instance through the newInstance() method that is strongly converted to a Robot object. Next we print the name of rc, which is obtained from the path we passed, so name is naturally the Robot class we want to create.

We use the rc.getDeclaredMethod () method to get a method object whose parameters correspond to the name of the method we want to get. Since this method is private, we set setAccessible() to true to indicate that reflection does not perform permission checks when applied.

Since the throwHello method requires arguments, we pass in Bob, and the final output is getHello result is Hello Bob

Through the above code, we get the Robot object and its method, which can be regarded as a preliminary application of reflection (the second half of the code belongs to the same as the same, not to repeat).

What is the difference between loadClass and forName?

The difference between class.forname and classLoder.loadClass is that the Class is initialized, while classloder.loadClass is not linked yet.

The forName method executes a static block of code in a class, whereas loadClass does not. Let’s take a simple example.

Take class.forname (” com.mysql.jdbc.driver “) as an example. The Driver class needs to execute static code blocks (new Driver) so forname cannot be loadClass. In contrast, springIoc adopts a strategy of lazyloading (delayed loading) when reading bean configuration. Using classLoader does not need to execute static code blocks, which speeds up initialization and saves relevant loading until the actual code execution. Therefore, these two methods have their own advantages and disadvantages and need to be determined according to the actual situation.

We’ve covered Java reflection in this article, and hopefully you’ve found it useful.