Java Reflection truy xuất biến, hàm private

Reflection là kĩ thuật rất cần thiết để lấy các thông tin của một kiểu dữ liệu. Dựa vào đó ta có thể kích hoạt (như các phương thức) hoặc tạo thể hiện của kiểu dữ liệu đó. Một ứng dụng quan trọng của reflection mà bạn có thể biết là Java Bean. Nhờ đó, các IDE (như NetBeans) có thể lấy được các thông tin và thiết lập giá trị cho các đối tượng.

Kiến trúc của Java Reflection API
Các lớp được dùng trong reflection nằm trong hai package là java.lang và java.lang.reflect. Package java.lang.reflect bao gồm ba lớp chính mà bạn cần biết là Constructor, Field và Method:
–      Class<T>: lớp này đại diện cho các lớp, interface và chứa các phương thức dùng để lấy các đối tượng kiểu Constructor, Field, Method,…
–      AccessibleObject: các kiểm tra về phạm vi truy xuất (public, private, protected) của field, method, constructor sẽ được bỏ qua. Nhờ đó bạn có thể dùng reflection để thay đổi, thực thi các thành phần này mà không cần quan tâm đến phạm vi truy xuất của nó.
–      Constructor: chứa các thông tin về một constructor của lớp.
–      Field: chứa các thông tin về một field của lớp, interface.
–      Method: chứa các thông tin về một phương thức của lớp, interface.
Java Reflection API

Ta xét một ví dụ sau dùng java reflection để truy xuất các thuộc tính private:

package com.example.reflection;
public class Circle {
    

    private double PI = 3.14;
    private int r;
    

    public Circle() {}
 
    public Circle(int r) { this.r = r;}
 
    private double getC(){ return 2 * PI * r; }
 
    private double getC(Integer r){ return 2 * PI * r;}
}

* Khởi tạo đối tượng:


Class<?> clazz = Class.forName("com.example.reflection.Circle");
Circle o = (Circle) clazz.newInstance();
 @Lưu ý: 
- Class Circle phải có constructor chuẩn không có sẽ bị lỗi java.lang.InstantiationException 
- Phải set thuộc tính 'accessible = true' không có sẽ bị lỗi java.lang.IllegalAccessException

* Truy xuất biến private PI trong Circle:

 Field pi = o.getClass().getDeclaredField("PI");
 pi.setAccessible(true);
 double PI = (Double) pi.get(o);

==> Kết quả: Lấy được PI = 3.14

* Truy xuất hàm private getC() không tham số:

Circle circle = new Circle(1);
Method method = circle.getClass().getDeclaredMethod("getC");
method.setAccessible(true);
double c = (Double) method.invoke(circle);

==> Kết quả: C = 6.28

* Truy xuất hàm private getC() với tham số r = 2:

Circle circle = new Circle(1);
Class[] paramType = {Integer.class};
Object[] param = {2};
Method method = circle.getClass().getDeclaredMethod("getC", paramType);
method.setAccessible(true);
double c = (Double) method.invoke(circle, param);

==> Kết quả: C = 12.56

SHARE THIS

0 comments: