Summary analysis based on reflection in Java

  • 2020-04-01 01:46:56
  • OfStack

It was really hard to understand what reflection was when you first started learning Java

Some books, even the most classic ones, explain things in a way that makes you feel confused. Maybe I'm too stupid

What's more, it's a bit disturbing to read on the Internet that reflection mechanisms need to be used more often in future learning frameworks

I just happened to read a little bit of the chapter and video on reflection and found that I could understand a little bit more

Now decided to go ahead, while reading and writing, by the way some of the main content and operations are recorded here

I think that for a simple person like me, the best way to learn may be to repeat

When I came across something I didn't understand, I stopped and relearned it. Although it took a lot of time, it had some effect on me

 

My understanding is that reflection is restoring the complete information of a class based on an already instantiated object

At least for me, I think the good thing about it is that it gave me another look at object orientation from the bottom up

X_x hates the thick ones on the other side, killing my brain cells

 

Class Class

If you want to complete reflection, you must understand the Class Class

Example 1: get package and class names by object

package org.siu;

class Test {

}

public class Demo {
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.getClass());
        System.out.println(t.getClass().getName());
    }
}

The result is as follows. Note how the package is compiled

The getClass() method here is inherited from the Object class by default

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483580.png ">

 

In Java, the Object Class is the parent of all classes, and likewise, the instantiated objects of all classes are instances of the Class Class

Thus, the concept of upward transformation and downward transformation is involved

Generics follow here due to the insecurity of the downward transition

(but I will say that the generic design here is dazzling! Nima, the whole Java syntax design is also dazzling, super disgusting!!

 

Instance 2: instantiation of a Class Class

Because Class classes have no constructor, there are three ways to instantiate Class classes:

Object. GetClass ()
Class. The Class
Class.forname ()

class Test {

}

public class Demo {
    public static void main(String[] args) {
        //A:
        Test t = new Test();
        Class<? extends Test> c1 = t.getClass();
        System.out.println(c1);

        //Method 2:
        //To avoid specificity, instead of the Test class, use the String class from the Java library
        Class<String> c2 = String.class;
        System.out.println(c2);

        //Three:
        //The forName() method throws an exception
        Class<?> c3 = null;
        try {
            c3 = Class.forName("Test");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(c3);
    }
}

Of these, the forName() method is important because it allows you to instantiate classes without Class uncertainty, which gives you more flexibility

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483581.png ">

 

Application of the Class Class

A method in the Class Class called newInstance() can be used to create a newInstance of the Class Class object

How do I put it? The Class object contains the reflected Class, and we're going to construct a new instance of that Class.

Example 3: a parameter-free construct object for a Class Class

public class Demo {
    public static void main(String[] args) {
        //The Class object is instantiated, and the forName() method throws an exception
        Class<?> c = null;
        try {
            //The full package and class names are required
            c = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //Generates a reference to a string
        String s = null;
        try {
            //Converts the constructed object down to a String class
            //The newInstance() method throws an exception
            s = (String) c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(" String length:  " + s.length());
    }
}

This constructs a new object in a parameterless form, as in normal mode

The same is true for constructing a new object through a parameter - free constructor

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483582.png ">

We know that there are constructors with arguments in a class in addition to an argument - free constructor

So how do you construct an object in reflection with arguments? Then look at

 

Instance 4: the argument construct object of the Class Class

import java.lang.reflect.Constructor;

public class Demo {
    //The following methods throw so many exceptions that, for the sake of code compactness, they are thrown directly to the virtual machine
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        char[] ch = {'h','e','l','l','o'};
        String s = null;
        //Gets the argument constructor for the Class object. The argument in the parentheses is written as: type.class
        Constructor<?> con = c.getConstructor(char[].class);
        //Use this constructor to construct a new string object that takes a char array as an argument
        s = (String) con.newInstance(ch);
        System.out.println(" Constructed string: " + s);
    }
}

Let's use the String class as an example, because the String class is used a lot, which is easy to understand

The important thing to note here is that the constructor method is obtained using the getConstructor() method

The parameter type is: the original type.class

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483583.png ">

Also, whether there are arguments or no arguments, the constructor used here must exist in the original class

So how do you know the details of the constructor, the normal method, the inherited parent, and so on in the original class? Then look at

 

Gets the structure of the class

To get the structure of the class through reflection we are going to import a new package here java.lang.reflect

Example 5: gets the constructor for the class

import java.lang.reflect.Constructor;
import java.util.Arrays;

public class Demo {
    //The following methods throw so many exceptions that, for the sake of code compactness, they are thrown directly to the virtual machine
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.Boolean");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //The getConstructors() method here returns a Constructor array
        Constructor<?>[] cons = c.getConstructors();
        //The way you print it, you can write it yourself, just so I can use arrays.tostring () and make do with it
        System.out.println(Arrays.toString(cons));
    }
}

I chose the Boolean class as an example, because there are only two constructors for the Boolean class

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483584.png ">

 

Example 6: gets the interface implemented by the class

import java.util.Arrays;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.Boolean");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Class<?>[] in = c.getInterfaces();
        System.out.println(Arrays.toString(in));
    }
}

There's nothing to tell. See what happens

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483585.png ">

 

Example 7: gets the parent class

public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.Boolean");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //Notice, this is not going to be an array, why?
        Class<?> su = c.getSuperclass();
        System.out.println(su);
    }
}

Remember, in Java, there is single inheritance and only one parent class

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483586.png ">

 

Example 8: get all the methods of the class

import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.Boolean");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] m = c.getMethods();
        //Well, this time I'll be kind enough to make a printable list
        for (int i = 0; i < m.length; i++) {
            System.out.println(m[i]);
        }
    }
}

Cut it out, look at it, just the meaning... These are all fairly simple examples

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483587.png ">

 

Instance 9: gets all the properties of this class

import java.lang.reflect.Field;

class Person {
    private String name;
    private int age;
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null;
        try {
            c = Class.forName("Person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Field[] f = c.getDeclaredFields();
        for (int i = 0; i < f.length; i++) {
            System.out.println(f[i]);
        }
    }
}

The getDeclaredFielsd() method gets all the properties, and getFields() only the public properties

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483588.png ">

 

Instance 10: gets the value of the property in this class

import java.lang.reflect.Field;

class Person {
    public String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person("zhangsan",12);

        Class<?> c = p.getClass();

        //Gets the value of the public property
        Field f1 = c.getField("name");
        //Get (p) indicates which object to get the value of
        String str = (String) f1.get(p);
        System.out.println(" Name:  " + str);

        //Gets the value of the private property
        Field f2 = c.getDeclaredField("age");
        //Age is a private property, so set the security check to true
        f2.setAccessible(true);
        int age = (int) f2.get(p);
        System.out.println(" Age:  " + age);
    }
}

Note that the setAccessible() method can be set to access and modify private properties

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483589.png ">

 

Frankly speaking, I haven't found anything in Java that can blind me yet

Each time, I write a bunch of tedious syntax to implement a gadget, or I call the API desperately and throw exceptions desperately

Code that is not sufficiently compact by itself becomes even more cumbersome

If I like a language, its characteristics must impress me before I can make something out of it

Obviously, Java doesn't make me happy, and maybe many programmers, like me, are forced to use it

Just to calm my lonely coding heart, let's move on

 

Example 11: modifying properties by reflection

import java.lang.reflect.Field;

class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String toString() {
        return " Name:  " + this.name;
    }
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person(" Two dogs ");
        System.out.println(p);
        Class<?> c = p.getClass();

        //Define the properties to modify
        Field f = c.getDeclaredField("name");
        f.setAccessible(true);
        //Modify the properties, passing in the object and value to be set
        f.set(p, " Zhang two eggs ");
        System.out.println(p);
    }
}

Several methods are related, if you do not understand the first familiar with the above examples

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483590.png ">

 

Instance 12: invoking a method through reflection

import java.lang.reflect.Method;

class Person {
    public void print(int i) {
        System.out.println(" I'm writing the Numbers:  " + i);
    }

    public static void say(String str) {
        System.out.println(" I'm talking about:  " + str);
    }
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        Class<?> c = p.getClass();

        //The getMethod() method needs to pass in the method name and the parameter type
        Method m1 = c.getMethod("print", int.class);
        //To invoke() means to invoke, you need to pass in an object and parameters
        m1.invoke(p, 10);

        Method m2 = c.getMethod("say", String.class);
        //Null here means not called by the object, which is a static method
        m2.invoke(null, " Your younger sister ");
    }
}

A normal argument method and a static method are demonstrated here

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483591.png ">

Now that you have all the arguments, it's easier to pass in an object without arguments

 

Example 13: manipulating an array by reflection

import java.lang.reflect.Array;

public class Demo {
    public static void main(String[] args) throws Exception {
        int[] arr = {1,2,3,4,5};
        Class<?> c = arr.getClass().getComponentType();

        System.out.println(" Array type:  " + c.getName());
        int len = Array.getLength(arr);
        System.out.println(" Array length:  " + len);
        System.out.print(" Traversal group:  ");
        for (int i = 0; i < len; i++) {
            System.out.print(Array.get(arr, i) + " ");
        }
        System.out.println();
        //Modify the array
        System.out.println(" The first element before modification:  " + Array.get(arr, 0));
        Array.set(arr, 0, 3);
        System.out.println(" The first element after modification:  " + Array.get(arr, 0));
    }
}

One thing to note here is that getComponentType() returns the Class of the array element

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013050318483592.png ">

 

That's all I'm going to do for the moment, and I'm going to read about the use of reflection in factory mode

Just replace it with the forName() method, nothing to say

I'm a Java beginner black, and I hate Java for its disgusting syntax and design

This is all for Android, to lay the foundation, to adapt to the work ahead


Related articles: