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:
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