First, let’s get to know a few categories.
Class(java.lang.Class)
A Class object is a special object, and each class has a Class object to create a "regular" object of that class. It can be obtained through the getClass() method of the object.
For example, we run this line of code:
The code copy is as follows:
System.out.println("test".getClass().toString());
The result is:
The code copy is as follows:
class java.lang.String
Field(java.lang.reflect.Field)
This class represents a field, which can be used to access the class
Next, let's create the test class:
The code copy is as follows:
class Book {
public String title;
public int length = 0;
public ArrayList<Page> pages = null;
@Override
public String toString() {
String sb = "Book:/n";
sb += "title="+title+"/n";
sb += "length=" + length + "/n";
sb += "pages=" + pages + "/n";
if (pages != null) {
for (Page page : pages) {
sb += page.toString();
}
}
return sb.toString();
}
}
class Page {
@Override
public String toString() {
return "page/n";
}
}
Call the following method to test the above class:
The code copy is as follows:
Book book = new Book();
System.out.println(book);
Its result is this:
The code copy is as follows:
Book:
title=null
length=0
pages=null
This is the initial state of the book object
We use the reflection mechanism to obtain the length field in the book object and modify it to view the results:
The code copy is as follows:
Book book = new Book();
Class<?> aClass = book.getClass();
Field field = aClass.getField("length");
field.setInt(book, 9);
System.out.println(book);
You can see that the running results are:
The code copy is as follows:
Book:
title=null
length=9
pages=null
It can be seen that the value of the length field has been modified.
The above modified is a simple field of int type. In fact, object fields like title field can also be modified. The following is an example:
The code copy is as follows:
Book book = new Book();
Class<?> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(String.class)){
field.set(book, "Grimm's fairy tale");
}else if(field.getType().equals(int.class)){
field.set(book, 199);
}
}
System.out.println(book);
The output result of the above code is:
The code copy is as follows:
Book:
title=Grimm's fairy tale
length=199
pages=null
In fact, all fields of String type are modified to "Grimm's Fairy Tale" and all fields of int type are modified to 199. We don't even know what this field means.
Next, we modify the pages field. This field is an ArrayList. We will create an ArrayList object and insert an object into it.
The code copy is as follows:
Book book = new Book();
Class<?> aClass = book.getClass();
Field[] fields = aClass.getFields();
for (Field field : fields) {
field.setAccessible(true);
if(field.getType().equals(ArrayList.class)){
String genric = field.getGenericType().toString();
String genricClass = genric.substring(
genric.indexOf('<') + 1,
genric.indexOf('>'));
Class<?> entityClass = Class.forName(genricClass);
Object obj = entityClass.newInstance();
ArrayList list = new ArrayList();
list.add(obj);
field.set(book, list);
}
}
System.out.println(book);
The output result is as follows:
The code copy is as follows:
Book:
title=null
length=0
pages=[page
]
Page
It can be seen that although we did not use the Page class directly, we still created a Page object.
The creation statement of the Page object is in the sentence: entityClass.newInstance(). The newInstance statement is an important method of Class object and is used to create the corresponding object of this class. Of course, the class constructor supports it. In addition, through the genGenericType method, we can get the type modifier of the field. Put it here, what you get is ArrayList<Page>. With this string, we can load the Page class and create a Page object through the class loader Class.forName.