Hívási módszerek futás közben a Java Reflection használatával

1. Áttekintés

Ebben a rövid cikkben gyorsan megnézzük, hogyan kell metódusok futás közbeni meghívása a Java Reflection API segítségével.

2. Felkészülés

Hozzunk létre egy egyszerű osztályt, amelyet a következő példákhoz használunk:

public class Műveletek {public double publicSum (int a, double b) {return a + b; } public static double publicStaticMultiply (float a, long b) {return a * b; } privát logikai privateAnd (logikai a, logikai b) {return a && b; } védett int védettMax (int a, int b) {return a> b? a: b; }}

3. A. Megszerzése Módszer Tárgy

Először meg kell szereznünk a Módszer objektum, amely tükrözi azt a módszert, amelyet meg akarunk hívni. A Osztály Az objektum, amely azt a típust képviseli, amelyben a módszert meghatározták, ennek két módját kínálja.

3.1. getMethod ()

Tudjuk használni getMethod () bármilyen nyilvános módszer megtalálására, legyen az statikus vagy példány, amelyet az osztály vagy annak bármely szuperosztálya határoz meg.

Első argumentumként a metódus nevét kapja, amelyet a metódus argumentumainak típusai követnek:

Metódus sumInstanceMethod = Operations.class.getMethod ("publicSum", int.osztály, kettős osztály); Metódus multiplyStaticMethod = Operations.class.getMethod ("publicStaticMultiply", float.class, long.class);

3.2. getDeclaredMethod ()

Tudjuk használni getDeclaredMethod () hogy bármelyik osztályban definiált módszert megkapjuk. Ez magában foglalja a nyilvános, védett, alapértelmezett hozzáférést, sőt a privát módszereket is, de kizárja az öröklött módszereket.

Ugyanazokat a paramétereket kapja, mint getMethod ():

Method andPrivateMethod = Operations.class.getDeclaredMethod ("privateAnd", logikai.osztály, logikai.osztály);
Metódus maxProtectedMethod = Operations.class.getDeclaredMethod ("protectedMax", int.class, int.class);

4. Módszerek meghívása

A ... val Módszer példány a helyén, most már hívhatunk invoke () az alapul szolgáló módszer végrehajtásához és a visszaküldött objektum megszerzéséhez.

4.1. Példamódszerek

Példány metódus meghívásához az első argumentum a invoke () példányának kell lennie Módszer amely tükrözi a hivatkozott módszert:

@Test public void givenObject_whenInvokePublicMethod_thenCorrect () {metódus sumInstanceMethod = Operations.class.getMethod ("publicSum", int.class, double.class); Operations operationInstance = new Operations (); Dupla eredmény = (Double) sumInstanceMethod.invoke (műveletekInstance, 1, 3); assertThat (eredmény, egyenlő To (4,0)); }

4.2. Statikus módszerek

Mivel ezekhez a módszerekhez nincs szükség példány meghívására, átadhatjuk nulla első érvként:

@Test public void givenObject_whenInvokeStaticMethod_thenCorrect () {Method multiplyStaticMethod = Operations.class.getDeclaredMethod ("publicStaticMultiply", float.class, long.class); Dupla eredmény = (Double) multiplyStaticMethod.invoke (null, 3.5f, 2); assertThat (eredmény, egyenlőTo (7.0)); }

5. A módszer hozzáférhetősége

Alapértelmezés szerint nem minden tükrözött módszer az hozzáférhető. Ez azt jelenti, hogy a JVM érvényesíti a hozzáférés-ellenőrzéseket, amikor meghívja őket.

Például, ha megpróbálunk privát metódust meghívni a meghatározó osztályán kívül, vagy egy védett metódust egy alosztályon vagy annak osztályán kívül, akkor kapunk egy IllegalAccessException:

@Test (várható = IllegalAccessException.class) public void givenObject_whenInvokePrivateMethod_thenFail () {Method andPrivateMethod = Operations.class.getDeclaredMethod ("privateAnd", logikai.osztály, logikai.osztály); Operations operationInstance = new Operations (); Logikai eredmény = (logikai érték) ésPrivateMethod.invoke (műveletekInstance, true, false); assertFalse (eredmény); } @Test (várható = IllegalAccessException.class) public void givenObject_whenInvokeProtectedMethod_thenFail () {Method maxProtectedMethod = Operations.class.getDeclaredMethod ("protectedMax", int.class, int.class); Operations operationInstance = new Operations (); Egész eredmény = (Egész) maxProtectedMethod.invoke (műveletekInstance, 2, 4); assertThat (eredmény, egyenlőTo (4)); }

Hívással setAccesible (true) tükrözött metódus objektumon a JVM elnyomja a hozzáférés-ellenőrzést és lehetővé teszi számunkra, hogy kivétel nélkül dobjuk fel a módszert:

@Test public void givenObject_whenInvokePrivateMethod_thenCorrect () {// ... andPrivateMethod.setAccessible (true); // ... logikai eredmény = (logikai érték) ésPrivateMethod.invoke (műveletekInstance, true, false); assertFalse (eredmény); } @Test public void givenObject_whenInvokeProtectedMethod_thenCorrect () {// ... maxProtectedMethod.setAccessible (true); // ... Egész eredmény = (Egész) maxProtectedMethod.invoke (műveletekInstance, 2, 4); assertThat (eredmény, egyenlőTo (4)); }

6. Következtetés

Ebben a gyors cikkben azt láthattuk, hogyan lehet reflektálás útján futás közben hívni egy osztály példányait és statikus módszereit. Bemutattuk azt is, hogy miként lehet megváltoztatni a visszaverődő metódusobjektumok hozzáférhető jelzőjét a Java hozzáférés-vezérlés ellenőrzésének elnyomására privát és védett módszerek meghívásakor.

Mint mindig, a példakód megtalálható a Githubon.