@@ -29,7 +29,7 @@ last_update: 2024-05-04
2929<a id =" intro " >  ; </a >
3030## What are method handles
3131Method handles are a low level mechanism used for method lookup and invocation. It is often compared to reflection,
32- because both the Reflection API and method handles provide means to invoke methods and constructors and access fields.
32+ because both the Reflection API and method handles provide means to invoke methods, constructors and access fields.
3333
3434What exactly is a method handle? It's a direct reference to a method, constructor, or field, which can be invoked.
3535The Method Handle API allows manipulations on top of simple pointer to the method, that allow us to insert or reorder the
@@ -43,15 +43,15 @@ The access checking for method handle invocations is done differently compared t
4343each call results in access checks for the caller. For method handles, the access is only checked when the method handle
4444is created.
4545
46- It is important to keep in mind, that if the method handle is created within a context where it can access non-public
46+ It is important to keep in mind that if the method handle is created within a context where it can access non-public
4747members, when passed outside, it can still access those non-public members. As a result, non-public members can
4848potentially be accessed from code where they shouldn't be accessible. It's a developer's responsibility to keep such
4949method handles private to their context. Alternatively, the method handle can be created with access limitations right
5050away using the appropriate lookup object.
5151
5252<a id =" lookup " >  ; </a >
5353## Method handle lookup
54- To create a method handle, we first need to create a [ ` Lookup ` ] ( javadoc:Lookup ) object, which acts as a factory for
54+ To create a method handle we first need to create a [ ` Lookup ` ] ( javadoc:Lookup ) object, which acts as a factory for
5555creating method handles. Depending on how the lookup object itself or the method handles are going to be used, we can
5656decide whether we should limit its access level.
5757
@@ -73,7 +73,7 @@ MethodHandles.Lookup lookup = MethodHandles.lookup();
7373
7474<a id =" methodtype " >  ; </a >
7575## Method type
76- To be able to look up a method handle, we also need to provide the type information of the method or field. The method
76+ Tolook up a method handle we also need to provide the type information of the method or field. The method
7777type information is represented as [ ` MethodType ` ] ( javadoc:MethodType ) object. To instantiate a ` MethodType ` ,
7878we have to provide the return type as the first parameter followed by all the argument types:
7979
@@ -85,7 +85,7 @@ MethodType methodType = MethodType.methodType(int.class /* the method returns in
8585Having the ` Lookup ` and the ` MethodType ` instances, we can look up the method handle. For instance methods, we should
8686use [ ` Lookup.findVirtual ` ] ( javadoc:MethodHandles.Lookup.findVirtual(Class,String,MethodType) ) , and for static methods
8787[ ` Lookup.findStatic ` ] ( javadoc:MethodHandles.Lookup.findStatic(Class,String,MethodType) ) . Both these methods accept the
88- following arguments: a ` Class ` , where the method is located, a method name represented as a ` String ` , and a ` MethodType `
88+ following arguments: a ` Class ` where the method is located, a method name represented as a ` String ` , and a ` MethodType `
8989instance.
9090
9191In the example below, we are using ` Lookup.findVirtual ` method to look up an instance method
@@ -409,7 +409,7 @@ If we try to pass the arguments that are already prefilled, we will fail with a
409409
410410### Filter arguments
411411We can use [ ` MethodHandles.filterArguments ` ] ( javadoc:MethodHandles.filterArguments(MethodHandle,int,MethodHandle...) )
412- to apply transformations to the arguments before invocation of the target method handle. To make it work, we have to provide:
412+ to apply transformations to arguments before invocation of the target method handle. To make it work, we have to provide:
413413
414414- The target method handle;
415415- The position of the first argument to transform;
@@ -418,7 +418,7 @@ to apply transformations to the arguments before invocation of the target method
418418If certain arguments don't require transformation, we can skip them by passing ` null ` . It's also possible to skip the
419419rest of the arguments entirely if we only need to transform a subset of them.
420420
421- Let's take a look at the following example .
421+ Let's reuse the method handle from the previous section and filter some its arguments before its invocation .
422422
423423``` java
424424MethodHandle targetMethodHandle = lookup. findStatic(Example . class, " test" ,
@@ -433,24 +433,26 @@ private static boolean negate(boolean original) {
433433}
434434```
435435
436- Let's also create a method that increments any given integer value:
436+ and also construct a method that increments any given integer value:
437437
438438``` java
439439private static int increment(int original) {
440440 return ++ original;
441441}
442442```
443443
444- Method handles for these transformation methods:
444+ We can obtain method handles for these transformation methods:
445445
446446``` java
447447MethodHandle negate = lookup. findStatic(Example . class, " negate" , MethodType . methodType(boolean . class, boolean . class));
448448MethodHandle increment = lookup. findStatic(Example . class, " increment" , MethodType . methodType(int . class, int . class));
449449```
450450
451- Now we can create a new method handle with transformations applied to two of the original arguments:
451+ and use them to get a new method handle having filtered arguments:
452452
453453``` java
454+ // applies filter 'increment' to argument at index 0, 'negate' to the last argument,
455+ // and passes the result to 'targetMethodHandle'
454456MethodHandle withFilters = MethodHandles . filterArguments(targetMethodHandle, 0 , increment, null , null , negate);
455457withFilters. invoke(3 , " abc" , 5L , false ); // outputs "4abc5true"
456458```
@@ -623,4 +625,4 @@ The biggest differences are:
623625- Method invocation is more performant with method handles due to a different access checking approach.
624626- Method handles don't provide any tooling for listing the class members and inspecting their properties.
625627- Method handles make it easy to wrap the direct pointers to methods and fields into more complicated logic which
626- includes argument and return value manipulations.
628+ includes argument and return value manipulations.
0 commit comments