שיטות שיחה בזמן ריצה באמצעות השתקפות ג'אווה

1. סקירה כללית

במאמר קצר זה, נבחן במהירות כיצד לעשות זאת להפעיל שיטות בזמן ריצה באמצעות Java Reflection API.

2. להתכונן

בואו ניצור מחלקה פשוטה בה נשתמש בדוגמאות הבאות:

פעולות מחלקה ציבורית {public double publicSum (int a, double b) {return a + b; } ציבורי סטטי פומבי כפול publicStaticMultiply (צף a, ארוך b) {החזר a * b; } פרטי בוליאני privateAnd (בוליאני a, בוליאני b) {להחזיר a & b; } מוגן int protectedMax (int a, int b) {להחזיר a> b? a: b; }}

3. השגת א שיטה לְהִתְנַגֵד

ראשית, עלינו להשיג שיטה אובייקט המשקף את השיטה שאנו רוצים להפעיל. ה מעמד האובייקט, המייצג את הסוג בו מוגדרת השיטה, מספק שתי דרכים לעשות זאת.

3.1. getMethod ()

אנחנו יכולים להשתמש getMethod () כדי למצוא כל שיטה ציבורית, בין אם זה סטטי או מופע שמוגדר בכיתה או בכל אחד ממחזורי העל שלה.

הוא מקבל את שם השיטה כארגומנט הראשון, ואחריו סוגי הטיעונים של השיטה:

שיטת sumInstanceMethod = Operations.class.getMethod ("publicSum", int.class, double.class); שיטה multiplyStaticMethod = Operations.class.getMethod ("publicStaticMultiply", float.class, long.class);

3.2. getDeclaredMethod ()

אנחנו יכולים להשתמש getDeclaredMethod () כדי לקבל כל שיטה המוגדרת בכיתה. זה כולל שיטות ציבוריות, מוגנות, ברירת מחדל ואפילו שיטות פרטיות, אך לא כולל שיטות תורשתיות.

הוא מקבל את אותם הפרמטרים כמו getMethod ():

Method andPrivateMethod = Operations.class.getDeclaredMethod ("privateAnd", בוליאני.קלאס, בוליאני.קלאס);
שיטה maxProtectedMethod = Operations.class.getDeclaredMethod ("protectedMax", int.class, int.class);

4. שיטות קריאה

עם ה שיטה למשל, אנחנו יכולים להתקשר עכשיו לעורר() לביצוע השיטה הבסיסית ולקבלת האובייקט שהוחזר.

4.1. שיטות מופע

להפעיל שיטת מופע, הטיעון הראשון ל לעורר() חייב להיות מופע של שיטה המשקף את השיטה בה מופעלת:

@Test public void givenObject_whenInvokePublicMethod_thenCorrect () {Method sumInstanceMethod = Operations.class.getMethod ("publicSum", int.class, double.class); פעולות פעולותInstance = פעולות חדשות (); תוצאה כפולה = (כפול) sumInstanceMethod.invoke (operationsInstance, 1, 3); assertThat (תוצאה, equalTo (4.0)); }

4.2. שיטות סטטיות

מכיוון ששיטות אלה אינן דורשות קריאה למופע, אנו יכולים לעבור ריק כטיעון הראשון:

@Test public void givenObject_whenInvokeStaticMethod_thenCorrect () {Method multiplyStaticMethod = Operations.class.getDeclaredMethod ("publicStaticMultiply", float.class, long.class); תוצאה כפולה = (כפול) multiplyStaticMethod.invoke (null, 3.5f, 2); assertThat (תוצאה, equalTo (7.0)); }

5. נגישות שיטה

כברירת מחדל, לא כל השיטות המשתקפות הן נגיש. המשמעות היא ש- JVM אוכף בדיקות בקרת גישה בעת הפעלתן.

למשל, אם ננסה לקרוא לשיטה פרטית מחוץ למחלקה המגדירה שלה או לשיטה מוגנת מחוץ למחלקה משנה או לחבילה של המחלקה שלה, נקבל IllegalAccessException:

@Test (צפוי = IllegalAccessException.class) חלל ציבורי givenObject_whenInvokePrivateMethod_thenFail () {Method andPrivateMethod = Operations.class.getDeclaredMethod ("privateAnd", בוליאני.קלאס, בוליאני.קלאס); פעולות פעולותInstance = פעולות חדשות (); תוצאה בוליאנית = (בוליאנית) ו- PrivateMethod.invoke (operationsInstance, true, false); assertFalse (תוצאה); } @Test (צפוי = IllegalAccessException.class) חלל ציבורי givenObject_whenInvokeProtectedMethod_thenFail () {שיטה maxProtectedMethod = Operations.class.getDeclaredMethod ("protectedMax", int.class, int.class); פעולות פעולותInstance = פעולות חדשות (); תוצאה שלמה = (שלם) maxProtectedMethod.invoke (operationsInstance, 2, 4); assertThat (תוצאה, שווה ל- (4)); }

על ידי התקשרות setAccessible (נכון) על אובייקט שיטה משתקף, ה- JVM מדכא את בדיקות בקרת הגישה ומאפשר לנו להפעיל את השיטה מבלי לזרוק חריג:

@Test הציבור בטל givenObject_whenInvokePrivateMethod_thenCorrect () {// ... andPrivateMethod.setAccessible (נכון); // ... תוצאה בוליאנית = (בוליאנית) ו- PrivateMethod.invoke (operationsInstance, true, false); assertFalse (תוצאה); } @Test הציבור בטל givenObject_whenInvokeProtectedMethod_thenCorrect () {// ... maxProtectedMethod.setAccessible (נכון); // ... תוצאה שלמה = (שלם) maxProtectedMethod.invoke (operationsInstance, 2, 4); assertThat (תוצאה, שווה ל- (4)); }

6. מסקנה

במאמר מהיר זה, ראינו כיצד לקרוא לשיטות מופע וסטטי של כיתה בזמן ריצה באמצעות השתקפות. הראינו גם כיצד לשנות את הדגל הנגיש באובייקטים של השיטה המשתקפת כדי לדכא בדיקות בקרת גישה של Java בעת הפעלת שיטות פרטיות ומוגנות.

כמו תמיד, ניתן למצוא את הקוד לדוגמא ב- Github.