Khám phá cơ chế phản chiếu trong Java

Mục lục

  1. Khái niệm phản chiếu
  2. Tác dụng của phản chiếu
  3. Cách lấy đối tượng Class
  4. Lấy đối tượng Constructor
  5. Lấy đối tượng Method
  6. 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);
    }
}

Thẻ: Java Reflection constructor method field

Đăng vào ngày 17 tháng 6 lúc 07:13