Mục lục
- Khái niệm phản chiếu
- Tác dụng của phản chiếu
- Cách lấy đối tượng Class
- Lấy đối tượng Constructor
- Lấy đối tượng Method
- Lấy đối tượng Field
1. Khái niệm phản chiếu
Phản chiếu (Reflection) là khả năng truy cập và phân tích cấu trúc của một lớp trong thời gian chạy. Trong quá trình thực thi, JVM có thể xác định tất cả các thuộc tính và phương thức của một lớp, cũng như gọi bất kỳ phương thức nào của một đối tượng.
2. Tác dụng của phản chiếu
- Xác định loại của một đối tượng tại runtime
- Tạo ra các đối tượng từ một lớp bất kỳ
- Kiểm tra các trường và phương thức của một lớp
- Gọi các phương thức của một đối tượng động
3. Cách lấy đối tượng Class
Có ba cách phổ biến để nhận được đối tượng Class:
Class<User> clazz1 = User.class;
Class<?> clazz2 = new User().getClass();
Class<?> clazz3 = Class.forName("com.yhf.entity.User");
4. Lấy đối tượng Constructor
Trong Java, các phương thức khởi tạo được biểu diễn dưới dạng đối tượng Constructor.
import com.qf.entity.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
Class<User> userClass = User.class;
// Lấy tất cả các constructor công khai
Constructor<?>[] constructors = userClass.getConstructors();
for (Constructor<?> c : constructors) {
System.out.println(c);
}
// Lấy tất cả constructor bao gồm private
Constructor<?>[] allConstructors = userClass.getDeclaredConstructors();
for (Constructor<?> c : allConstructors) {
System.out.println(c);
}
// Lấy constructor cụ thể
Constructor<User> noArgCons = userClass.getConstructor((Class[]) null);
Constructor<User> stringArgCons = userClass.getConstructor(String.class);
Constructor<User> intArgCons = userClass.getDeclaredConstructor(int.class);
// Tạo đối tượng thông qua constructor
User user1 = noArgCons.newInstance();
User user2 = stringArgCons.newInstance("Người dùng");
intArgCons.setAccessible(true);
User user3 = intArgCons.newInstance(25);
}
}
5. Lấy đối tượng Method
Phương thức trong lớp được biểu diễn bởi đối tượng Method.
import java.lang.reflect.Method;
public class MethodDemo {
public static void main(String[] args) throws Exception {
Class<User> userClass = User.class;
// Lấy tất cả các phương thức công khai và kế thừa từ Object
Method[] methods = userClass.getMethods();
for (Method m : methods) {
System.out.println(m);
}
// Lấy tất cả các phương thức trong lớp hiện tại
Method[] declaredMethods = userClass.getDeclaredMethods();
for (Method m : declaredMethods) {
System.out.println(m);
}
// Lấy một phương thức cụ thể
Method eatMethod = userClass.getMethod("eat", (Class[]) null);
Method eatWithParam = userClass.getMethod("eat", String.class);
Method sleepMethod = userClass.getDeclaredMethod("sleep", (Class[]) null);
// Gọi phương thức
User user = userClass.getConstructor((Class[]) null).newInstance(null);
eatMethod.invoke(user, (Object[]) null);
eatWithParam.invoke(user, "thức ăn");
sleepMethod.setAccessible(true);
sleepMethod.invoke(user, (Object[]) null);
}
}
6. Lấy đối tượng Field
Trường dữ liệu trong lớp được biểu diễn bởi đối tượng Field.
import java.lang.reflect.Field;
public class FieldDemo {
public static void main(String[] args) throws Exception {
Class<Person> personClass = Person.class;
// Lấy tất cả các trường công khai
Field[] publicFields = personClass.getFields();
for (Field f : publicFields) {
System.out.println(f);
}
// Lấy tất cả các trường (bao gồm private)
Field[] allFields = personClass.getDeclaredFields();
for (Field f : allFields) {
System.out.println(f);
}
// Lấy trường cụ thể
Field nameField = personClass.getDeclaredField("name");
Field ageField = personClass.getField("age");
Field sexField = personClass.getDeclaredField("sex");
// Gán giá trị cho trường
Person person = personClass.getConstructor((Class[]) null).newInstance(null);
ageField.set(person, 18);
sexField.setAccessible(true);
sexField.set(person, 'M');
System.out.println(person);
}
}