Cách gọi một method tại Runtime sử dụng Java Reflection

Trong bài viết ngắn này chúng ta sẽ cùng nhau tìm hiểu cách gọi một method tại thời điểm runtime sử dụng Java Reflection API.

Đầu tiên chúng ta cần chuẩn bị một Operations class như sau

public class Operations {
    public double publicSum(int a, double b) {
        return a + b;
    }

    public static double publicStaticMultiply(float a, long b) {
        return a * b;
    }

    private boolean privateAnd(boolean a, boolean b) {
        return a && b;
    }

    protected int protectedMax(int a, int b) {
        return a > b ? a : b;
    }
}

Method object

Trong Java Reflection mọi thao tác với một method bất kỳ được định nghĩa bên trong một class đều thông qua Method class, với Method instance chúng ta có thể thực hiện rất nhiều thao tác lên một method mà instance này nó đang trỏ đến.

getMethod

Chúng ta có thể sử dụng getMethod() trong Java Reflection để lấy bất kỳ public, static method nào được định nghĩa bên trong một class hoặc các class cha của nó.

Ví dụ trong Operations class chúng ta có thể lấy 2 Method instance trỏ đến publicSum()publicStaticMultiply() được định nghĩa bên trong nó.

Method sumInstanceMethod
  = Operations.class.getMethod("publicSum", int.class, double.class);

Method multiplyStaticMethod
  = Operations.class.getMethod(
    "publicStaticMultiply", float.class, long.class);

getDeclaredMethod

Với getDeclaredMethod() chúng ta có thể truy xuất bất kỳ method nào được định nghĩa bên trong một class thậm chí là các private method. Tuy nhiên method này sẽ không thể truy xuất được các method được định trong class cha của nó.

Method andPrivateMethod
  = Operations.class.getDeclaredMethod(
    "privateAnd", boolean.class, boolean.class);

Method maxProtectedMethod
  = Operations.class.getDeclaredMethod("protectedMax", int.class, int.class);

Cách gọi method bằng Java Reflection

Sau khi lấy được các Method instance tương ứng với method trong một class mà chúng ta muốn gọi. Thì bây giờ chúng ta có dễ gọi thực thi những method này thông qua Java Reflection

Public method

Đối với public method thì công việc này khá dễ dàng chúng ta chỉ cần sử dụng invoke() được cung cấp sẵn trong Method class.

public class Main {

    public static void main(String[] args) throws Exception {
        Method sumInstanceMethod
                = Operations.class.getMethod("publicSum", int.class, double.class);

        Operations operationsInstance = new Operations();
        Double result
                = (Double) sumInstanceMethod.invoke(operationsInstance, 1, 3);
        System.out.println("Value: " + result);
    }

}

Output

Value: 4.0

Static method

Đối với static method chúng ta không cần truyền Object instance ở tham số đầu tiên mà thay vào đó chúng ta chỉ cần truyền một giá trị null thay thế.

public class Main {

    public static void main(String[] args) throws Exception {
        Method multiplyStaticMethod
                = Operations.class.getDeclaredMethod(
                "publicStaticMultiply", float.class, long.class);

        Double result
                = (Double) multiplyStaticMethod.invoke(null, 3.5f, 2);
        System.out.println("Value: " + result);
    }

}

Output

Value: 7.0

Private & Protected method

Đối với 2 loại protected và private method chúng ta không thể gọi trực tiếp chúng thông qua Java Reflection mà trước đó chúng ta phải sử dụng method setAccesible(true) để cấp quyền truy cập vào protected và private method.

public class Main {

    public static void main(String[] args) throws Exception {
        Method andPrivateMethod
                = Operations.class.getDeclaredMethod(
                "privateAnd", boolean.class, boolean.class);
        andPrivateMethod.setAccessible(true);
        Operations operationsInstance = new Operations();
        Boolean result
                = (Boolean) andPrivateMethod.invoke(operationsInstance, true, false);
        System.out.println("Value: " + result);
    }

}

Output

Value: false

Tương tự với protected method

public class Main {

    public static void main(String[] args) throws Exception {
        Method maxProtectedMethod
                = Operations.class.getDeclaredMethod(
                "protectedMax", int.class, int.class);
        maxProtectedMethod.setAccessible(true);
        Operations operationsInstance = new Operations();
        Integer result
                = (Integer) maxProtectedMethod.invoke(operationsInstance, 2, 4);
        System.out.println("Value: " + result);
    }

}

Output:

Value: 4

Tóm lược

Như vậy qua bài viết này chúng ta đã biết cách gọi một method kể cả đó là private method thông qua Java Reflection. Hãy như sử dụng setAccessible() để nhận quyền truy cập vào chúng trước khi thực hiện lời gọi hàm nha.

Nguồn tham khảo: Baeldung

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x