When I first started learning Java, it was really difficult to understand what reflection was.
Some books, even very classic ones, explain things in a way that makes people feel confused. Maybe I am just too stupid.
Moreover, it is said online that the reflection mechanism needs to be used frequently when learning frameworks in the future, which always makes people feel a little uneasy.
I just accidentally watched some chapters and videos explaining reflection, and I think I can understand it a little better.
Now I decided to work hard, read and write at the same time, and record some main contents and operations here.
I think, for a stupid person like me, maybe the best way to learn is to repeat
When I encounter something I don’t understand, I stop and learn it all over again. Although it wastes a lot of time, it also has some effect on me.
My understanding is: the so-called reflection is to restore the complete information of the class based on an already instantiated object.
At least for me, I think the benefit it brings to me is that it allows me to understand object-oriented from bottom to top.
x_x Here I hate those thick heads again, they killed all my brain cells.
Class classIf you want to complete reflection, you must understand the Class class
Example 1: Obtain package name and class name through objectclass 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 compilation results are as follows, just pay attention to how the package is compiled.
The getClass() method here is inherited from the Object class by default.
In Java, the Object class is the parent class of all classes. Similarly, the instantiated objects of all classes are also instances of the Class class.
Therefore, this will involve the concepts of upward transformation and downward transformation
Generics will also follow here due to the insecurity of downward casts.
(But what I want to say is that the generic design here is very dazzling! Damn, the syntax design of the entire Java is also dazzling, super disgusting!!!)
Example 2: Instantiation of Class classSince the Class class has no constructor, the way to instantiate the Class class is a bit special. There are three ways:
Object.getClass()}
public class Demo {
public static void main(String[] args) {
//Method 1:
Test t = new Test();
Class<? extends Test> c1 = t.getClass();
System.out.println(c1);
//Method 2:
//In order to avoid specificity, the Test class is not used here, but the String class in the java library is used.
Class<String> c2 = String.class;
System.out.println(c2);
//Method 3:
//forName() method will throw an exception
Class<?> c3 = null;
try {
c3 = Class.forName("Test");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c3);
}
}
There is a method in the Class class called newInstance(), which can be used to create a new instance of the Class class object
How to say it? The content contained in the Class object is the reflected class. We need to construct a new instance (new object) of that class.
Example 3: Constructing object without parameters of Class class //Generate a reference to a string
String s = null;
try {
//Downcast the constructed object to the String class
//newInstance() method will throw 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, just like in normal mode
Constructing a new object through the no-argument constructor is the same as
We know that in addition to parameterless constructors, there are also parameterized constructors in a class.
So how to construct objects in the form of parameters in reflection? Read on
Example 4: Parameterized constructed object of Class class public class Demo {
//The following methods throw too many exceptions. For the sake of code compactness, they are thrown directly to the virtual machine here.
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;
//Get the parameterized constructor of the Class object. The parameters in the brackets are written as: type.class
Constructor<?> con = c.getConstructor(char[].class);
//Use this construction method to construct a new string object, the parameter is a char array
s = (String) con.newInstance(ch);
System.out.println("Constructed string: " + s);
}
}
We still use the String class as an example, because the String class is used more often and is easier to understand.
What needs to be noted here is that the constructor needs to be obtained using the getConstructor() method
As for the parameter type, it is: original type.class
Another point is that whether it has parameters or no parameters, the construction method used here must exist in the original class.
So, how can we know the detailed information such as the constructor method, ordinary method, inherited parent class and so on in the original class? Read on
Get the structure of the classTo obtain the structure of a class through reflection, we need to import a new package java.lang.reflect
Example 5: Obtain the constructor of a class public class Demo {
//The following methods throw too many exceptions. For the sake of code compactness, they are thrown directly to the virtual machine here.
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();
//You can write the printing method yourself. For convenience, I use Arrays.toString() to make do.
System.out.println(Arrays.toString(cons));
}
}
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));
}
}
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();
//Okay, this time I will be merciful and write a printout list.
for (int i = 0; i < m.length; i++) {
System.out.println(m[i]);
}
}
}
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 can get all properties, and getFields() can only get public properties.
Example 10: Get the value of the attribute in this class 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();
//Get the value of the public attribute
Field f1 = c.getField("name");
//get(p) indicates which object value is to be obtained
String str = (String) f1.get(p);
System.out.println("Name: " + str);
//Get the value of the private attribute
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);
}
}
Frankly speaking, I haven’t found any knowledge in Java that can blind my titanium eyes.
Every time, I have to write a bunch of tedious syntax to implement a gadget, or else I have to call the API desperately and throw exceptions desperately.
Make code that is not compact enough become cumbersome
If I like a language, its own characteristics must impress me before I can use it to make something.
Obviously, Java does not make me happy. Maybe many programmers like me are forced to use Java.
Just to appease my lonely coding heart, read on below
Reflection Application Example 11: Modify attributes through reflection 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("王二狗");
System.out.println(p);
Class<?> c = p.getClass();
//Define the properties to be modified
Field f = c.getDeclaredField("name");
f.setAccessible(true);
//Modify properties and pass in the object and value to be set
f.set(p, "Zhang Erdan");
System.out.println(p);
}
}
class Person {
public void print(int i) {
System.out.println("I am writing numbers: " + i);
}
public static void say(String str) {
System.out.println("I'm saying: " + str);
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Person p = new Person();
Class<?> c = p.getClass();
//getMethod() method needs to pass in the method name and parameter type
Method m1 = c.getMethod("print", int.class);
//invoke() means calling and needs to pass in objects and parameters
m1.invoke(p, 10);
Method m2 = c.getMethod("say", String.class);
//The null here means not called by the object, that is, a static method
m2.invoke(null, "your sister");
}
}
Here is a demonstration of a normal parameterized method and a static method
Now that all the parameters are written out, the ones without parameters are even simpler. Just pass in an object directly.
Example 13: Manipulating arrays through reflection 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("Traverse the array: ");
for (int i = 0; i < len; i++) {
System.out.print(Array.get(arr, i) + " ");
}
System.out.println();
//modify array
System.out.println("The first element before modification: " + Array.get(arr, 0));
Array.set(arr, 0, 3);
System.out.println("The modified first element: " + Array.get(arr, 0));
}
}
That’s all for the time being. The book I read also includes the application of reflection in factory mode.
It’s nothing more than replacing it with the forName() method. There’s nothing much to say.
I am a beginner in Java. I hate the disgusting syntax and design of Java.
This is all for Android, to lay the foundation, and to adapt to future work.