Skip to content

Commit 14b6ae6

Browse files
committed
some grammer, small reduction in repeated code"
1 parent 5b008b4 commit 14b6ae6

File tree

1 file changed

+17
-17
lines changed

1 file changed

+17
-17
lines changed

app/pages/learn/01_tutorial/04_mastering-the-api/02_invoke/00_methodhandle.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ category_order: 1
88
layout: learn/tutorial.html
99
subheader_select: tutorials
1010
main_css_id: learn
11-
description: "What are method handles, how are they different from the Reflection API, and what tooling do they provide?"
11+
description: "Method handles, how they are different from the Reflection API, and the tooling they provide."
1212
author: ["NataliiaDziubenko"]
1313
toc:
1414
- What are method handles {intro}
@@ -23,7 +23,7 @@ toc:
2323
- Method Handles vs Reflection API {vsreflection}
2424
- Conversion between Reflection API and method handles {unreflect}
2525
- Conclusion {conclusion}
26-
last_update: 2024-05-04
26+
last_update: 2024-05-30
2727
---
2828

2929
<a id="intro">&nbsp;</a>
@@ -132,8 +132,6 @@ handle with adjusted types that would strictly match the types of provided argum
132132
invoke the adjusted method handle using `invokeExact`.
133133

134134
```java
135-
MethodType replaceMethodType = MethodType.methodType(String.class, char.class, char.class);
136-
MethodHandle replaceMethodHandle = lookup.findVirtual(String.class, "replace", replaceMethodType);
137135
String result = (String) replaceMethodHandle.invoke((Object)"dummy", (Object)'d', (Object)'m'); // would fail with `invokeExact`
138136
```
139137

@@ -418,14 +416,14 @@ to apply transformations to arguments before invocation of the target method han
418416
If certain arguments don't require transformation, we can skip them by passing `null`. It's also possible to skip the
419417
rest of the arguments entirely if we only need to transform a subset of them.
420418

421-
Let's reuse the method handle from the previous section and filter some its arguments before its invocation.
419+
Let's reuse the method handle from the previous section and filter some of its arguments before invocation.
422420

423421
```java
424422
MethodHandle targetMethodHandle = lookup.findStatic(Example.class, "test",
425423
MethodType.methodType(void.class, int.class, String.class, long.class, boolean.class));
426424
```
427425

428-
Let's create a method that transforms any `boolean` value by negating it:
426+
Then we create a method that transforms any `boolean` value by negating it:
429427

430428
```java
431429
private static boolean negate(boolean original) {
@@ -448,7 +446,7 @@ MethodHandle negate = lookup.findStatic(Example.class, "negate", MethodType.meth
448446
MethodHandle increment = lookup.findStatic(Example.class, "increment", MethodType.methodType(int.class, int.class));
449447
```
450448

451-
and use them to get a new method handle having filtered arguments:
449+
and use them to get a new method handle having filtered the arguments:
452450

453451
```java
454452
// applies filter 'increment' to argument at index 0, 'negate' to the last argument,
@@ -471,7 +469,7 @@ private static void target(int ignored, int sum, int a, int b) {
471469
```
472470

473471
Using `foldArguments` we can pre-process a subset of its arguments and insert the resulting value as another
474-
argument and proceed to execution of the `target` method.
472+
argument and proceed to the execution of the `target` method.
475473

476474
In our example, we have arguments `int a, int b` at the end. We can pre-process any amount of arguments, but they all
477475
must be at the end. Let's say, we would like to calculate a sum of these two values `a` and `b`, so let's create a method
@@ -499,10 +497,9 @@ MethodHandle preProcessedArguments = MethodHandles.foldArguments(targetMethodHan
499497
```
500498

501499
The `foldArguments` method accepts:
502-
- Target method handle, in our case the one pointing to `target` method;
503-
- `int` number specifying the starting position of arguments related to folding. In our case, the `sum` argument
504-
is located at position `1`, so we passed `1`. If we skip this argument, `pos` will default to `0`.
505-
- Combiner method handle, in our case it's the one pointing to `sum` method.
500+
- `MethodHandle` *target*: The target method handle, in our case the one pointing to the `target` method.
501+
- `int` *pos*: An integer specifying the starting position of arguments related to folding. In our case, the `sum` argument is located at position `1`, so we passed `1`. If we skip this argument, `pos` will default to `0`.
502+
- `MethodHandle` *combiner*: The combiner method handle, in our case the one pointing to the `sum` method.
506503

507504
At the end, we can invoke the resulting method handle and pass all the arguments except `sum` which is going to be
508505
pre-calculated:
@@ -512,7 +509,7 @@ preProcessedArguments.invokeExact(10000, 1, 2); // outputs: "1 + 2 equals 3 and
512509
```
513510

514511
It is possible that the combiner method processes values but doesn't return anything. In this case, there is no need
515-
for a result placeholder in `target` method argument list.
512+
for a result placeholder in the `target` method argument list.
516513

517514
### Filter return value
518515
Similarly to arguments, we can use an adapter that will apply transformations to the return value.
@@ -551,16 +548,20 @@ System.out.println(getSomeUppercaseString.invoke()); // outputs: "MUMMY"
551548
<a id="vsreflection">&nbsp;</a>
552549
## Method Handles vs Reflection API
553550
Method handles were introduced in [JDK7](https://docs.oracle.com/javase/7/docs/index.html) as a tool to assist
554-
compiler and language runtime developers. They were never meant to replace reflection. The Reflection API offers something
551+
compiler and language runtime developers. They were never meant to replace reflection.
552+
553+
[The Reflection API](id:api.reflection) offers something
555554
that method handles cannot, which is listing the class members and inspecting their properties. Method handles, on the
556-
other hand, can be transformed and manipulated in a way that is not possible with Reflection API.
555+
other hand, can be transformed and manipulated in a way that is not possible with the Reflection API.
557556

558557
When it comes to method invocation, there are differences related to access checking and security considerations. The
559558
Reflection API performs access checking against every caller, on every call, while for method handles, access is
560559
checked only during construction. This makes invocation through method handles faster than through reflection.
561560
However, certain precautions have to be taken so the method handle is not passed to the code where it shouldn't be
562561
accessible.
563562

563+
You can learn more about Reflection in [this tutorial](id:api.reflection).
564+
564565
<a id="unreflect">&nbsp;</a>
565566
## Conversion between Reflection API and method handles
566567
The `Lookup` object can be used to convert Reflection API objects to behaviorally equivalent method handles, which
@@ -613,8 +614,7 @@ Field field = MethodHandles.reflectAs(Field.class, getterMethodHandle); // same
613614

614615
<a id="conclusion">&nbsp;</a>
615616
## Conclusion
616-
In this tutorial, we have looked into the method handle mechanism and learned how to efficiently use it. We now know,
617-
that method handles provide a means for efficient method invocation, but this mechanism is not meant to replace the
617+
In this tutorial, we have looked into the method handle mechanism and learned how to efficiently use it. We now know that method handles provide a means for efficient method invocation, but this mechanism is not meant to replace the
618618
Reflection API.
619619

620620
Method handles offer a performance advantage for method invocation due to a different access checking approach. However,

0 commit comments

Comments
 (0)