Mục lục
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() và 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