diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java index 812f26f58cc16..69b1f2553293f 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -268,7 +268,7 @@ * *
+ * } * Each of the above calls to {@code invokeExact} or plain {@code invoke} * generates a single invokevirtual instruction with * the symbolic type descriptor indicated in the following comment. @@ -695,7 +695,7 @@ public MethodType type() { * It can therefore be used as a bridge between native or reflective code and method handles. * @apiNote * This call is approximately equivalent to the following code: - *{@code + * {@snippet lang="java" : Object x, y; String s; int i; MethodType mt; MethodHandle mh; MethodHandles.Lookup lookup = MethodHandles.lookup(); @@ -304,7 +304,7 @@ mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt); mh.invokeExact(System.out, "Hello, world."); // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V - * }
+ * } * * @param arguments the arguments to pass to the target * @return the result returned by the target @@ -740,9 +740,9 @@ public Object invokeWithArguments(Object... arguments) throws Throwable { * of the argument list. *{@code + * {@snippet lang="java" : * // for jumbo argument lists, adapt varargs explicitly: * int N = (arguments == null? 0: arguments.length); * int M = this.type.parameterCount(); @@ -718,7 +718,7 @@ public MethodType type() { * // Handle fixed arity and non-jumbo variable arity invocation. * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0); * Object result = invoker.invokeExact(this, arguments); - * }
* This method is also equivalent to the following code: - *
+ * } *{@code + * {@snippet lang="java" : * invokeWithArguments(arguments.toArray()) - * }
* Jumbo-sized lists are acceptable if this method handle has variable arity. * See {@link #invokeWithArguments(Object[])} for details. @@ -1008,7 +1008,7 @@ private static boolean isBuiltinLoader(ClassLoader loader) { * if the array does not have the correct number of elements. *
* Here are some simple examples of array-spreading method handles: - *
+ * } * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments * @param arrayLength the number of arguments to spread from an incoming array argument * @return a new method handle which spreads its final array argument, @@ -1080,7 +1080,7 @@ public MethodHandle asSpreader(Class> arrayType, int arrayLength) { * argument to indicate at which position in the parameter list the spreading should take place. * * @apiNote Example: - *{@code + * {@snippet lang="java" : MethodHandle equals = publicLookup() .findVirtual(String.class, "equals", methodType(boolean.class, Object.class)); assert( (boolean) equals.invokeExact("me", (Object)"me")); @@ -1050,7 +1050,7 @@ private static boolean isBuiltinLoader(ClassLoader loader) { assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C')); MethodHandle caToString2 = caString3.asSpreader(char[].class, 2); assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray())); - * }
+ * } * @param spreadArgPos the position (zero-based index) in the argument list at which spreading should start. * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments * @param arrayLength the number of arguments to spread from an incoming array argument @@ -1179,14 +1179,14 @@ private void spreadArrayChecks(Class> arrayType, int arrayLength) { * .withVarargs(mh.isVarargsCollector())} *{@code + * {@snippet lang="java" : MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class)); MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2); Object[] ints = new Object[]{3, 9, 7, 7}; @@ -1088,7 +1088,7 @@ public MethodHandle asSpreader(Class> arrayType, int arrayLength) { assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0); assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0); assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0); - * }
* This call is approximately equivalent to the following code: - *
+ * } * @param makeVarargs true if the return method handle should have variable arity behavior * @return a method handle of the same type, with possibly adjusted variable arity behavior * @throws IllegalArgumentException if {@code makeVarargs} is true and @@ -1236,7 +1236,7 @@ public MethodHandle withVarargs(boolean makeVarargs) { * or {@link #withVarargs withVarargs} instead. *{@code + * {@snippet lang="java" : * if (makeVarargs == isVarargsCollector()) * return this; * else if (makeVarargs) * return asVarargsCollector(type().lastParameterType()); * else * return asFixedArity(); - * }
* Here are some examples of array-collecting method handles: - *
+ * } *{@code + * {@snippet lang="java" : MethodHandle deepToString = publicLookup() .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class)); assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"})); @@ -1262,7 +1262,7 @@ public MethodHandle withVarargs(boolean makeVarargs) { .findStatic(Arrays.class, "toString", methodType(String.class, long[].class)) .asCollector(long[].class, 1); assertEquals("[123]", (String) longsToString.invokeExact((long)123)); - * }
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector * variable-arity method handle}, even if the original target method handle was. @@ -1296,7 +1296,7 @@ public MethodHandle asCollector(Class> arrayType, int arrayLength) { * index is zero-based. * * @apiNote Examples: - *
+ * } *{@code + * {@snippet lang="java" : StringWriter swr = new StringWriter(); MethodHandle swWrite = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).bindTo(swr); MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4); @@ -1306,7 +1306,7 @@ public MethodHandle asCollector(Class> arrayType, int arrayLength) { assertEquals("BCPQRS", swr.toString()); swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1); assertEquals("BCPQRSZ", swr.toString()); - * }
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector * variable-arity method handle}, even if the original target method handle was. @@ -1459,7 +1459,7 @@ boolean asCollectorChecks(Class> arrayType, int pos, int arrayLength) { * It may (or may not) return the original variable arity method handle. *
* Here is an example, of a list-making variable arity method handle: - *
+ * } *{@code + * {@snippet lang="java" : MethodHandle deepToString = publicLookup() .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class)); MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class); @@ -1481,7 +1481,7 @@ boolean asCollectorChecks(Class> arrayType, int pos, int arrayLength) { List ls = (List) asList.invoke((Object)argv); assertEquals(1, ls.size()); assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0))); - * }
* Discussion: * These rules are designed as a dynamically-typed variation @@ -1553,7 +1553,7 @@ public boolean isVarargsCollector() { * previous argument to {@code asVarargsCollector}. *
* Here is an example, of a list-making variable arity method handle: - *
+ * } * * @return a new method handle which accepts only a fixed number of arguments * @see #asVarargsCollector @@ -1668,9 +1668,9 @@ public Optional{@code + * {@snippet lang="java" : MethodHandle asListVar = publicLookup() .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class)) .asVarargsCollector(Object[].class); @@ -1572,7 +1572,7 @@ public boolean isVarargsCollector() { assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString()); assertEquals(1, ((List) asListVar.invoke((Object)argv)).size()); assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); - * }
+ * } *{@code + * {@snippet lang="java" : * "MethodHandle" + type().toString() - * }
* (Note: Future releases of this API may add further information
* to the string representation.
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
index 3d202c8d57839..aa319c1607af6 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
@@ -806,12 +806,11 @@ public static
* The {@link #lookup()} factory method produces a {@code Lookup} object
* with {@code null} previous lookup class.
@@ -2573,14 +2572,14 @@ public String toString() {
* If the returned method handle is invoked, the method's class will
* be initialized, if it has not already been initialized.
* Example:
- *
* Example:
- * Example:
- * Example:
- *
* This is almost equivalent to the following code, with some differences noted below:
- *
* This method is equivalent to the following code (though it may be more efficient):
- *
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
* variable-arity method handle}, even if the original target method handle was.
@@ -5234,7 +5233,7 @@ private static Class>[] insertArgumentsChecks(MethodHandle target, int insCoun
* they will come after.
*
* Example:
- *
* This method is also equivalent to the following code:
*
* This method is also equivalent to the following code:
* Example:
- * Here is pseudocode for the resulting adapter. In the code, {@code T}
* denotes the return type of both the {@code target} and resulting adapter.
* {@code P}/{@code p} and {@code B}/{@code b} represent the types and values
@@ -5535,13 +5534,13 @@ public static MethodHandle dropReturn(MethodHandle target) {
* return types of the {@code filter[i]} handles. The latter accept arguments
* {@code v[i]} of type {@code V[i]}, which also appear in the signature of
* the resulting adapter.
- *
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
* variable-arity method handle}, even if the original target method handle was.
@@ -5670,7 +5669,7 @@ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHan
* In all cases, {@code pos} must be greater than or equal to zero, and
* {@code pos} must also be less than or equal to the target's arity.
* Example:
- * Here is pseudocode for the resulting adapter. In the code, {@code T}
* represents the return type of the {@code target} and resulting adapter.
* {@code V}/{@code v} stand for the return type and value of the
@@ -5707,7 +5706,7 @@ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHan
* adapter's signature and arguments, where they surround
* {@code B}/{@code b}, which represent the parameter types and arguments
* to the {@code filter} (if any).
- *
* A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to
* one which first "folds" the affected arguments, and then drops them, in separate
* steps as follows:
- * Example:
- * Here is pseudocode for the resulting adapter. In the code,
* {@code T}/{@code t} represent the result type and value of the
* {@code target}; {@code V}, the result type of the {@code filter}; and
* {@code A}/{@code a}, the types and values of the parameters and arguments
* of the {@code target} as well as the resulting adapter.
- *
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
* variable-arity method handle}, even if the original target method handle was.
@@ -5879,14 +5878,14 @@ private static void filterReturnValueChecks(MethodType targetType, MethodType fi
* applied to the return value of the original handle; if the filter specifies more than one parameters,
* then any remaining parameter is appended to the adapter handle. In other words, the adaptation works
* as follows:
- *
* If the filter handle is a unary function, then this method behaves like {@link #filterReturnValue(MethodHandle, MethodHandle)}.
*
@@ -5943,7 +5942,7 @@ private static void filterReturnValueChecks(MethodType targetType, MethodType fi
* arguments will not need to be live on the stack on entry to the
* target.)
* Example:
- * Here is pseudocode for the resulting adapter. In the code, {@code T}
* represents the result type of the {@code target} and resulting adapter.
* {@code V}/{@code v} represent the type and value of the parameter and argument
@@ -5966,7 +5965,7 @@ private static void filterReturnValueChecks(MethodType targetType, MethodType fi
* position. {@code B}/{@code b} represent the types and values of the
* {@code target} parameters and arguments that follow the folded parameters
* and arguments.
- *
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
* variable-arity method handle}, even if the original target method handle was.
@@ -6011,7 +6010,7 @@ public static MethodHandle foldArguments(MethodHandle target, MethodHandle combi
* 0.
*
* @apiNote Example:
- * Here is pseudocode for the resulting adapter. In the code, {@code T}
* represents the result type of the {@code target} and resulting adapter.
* {@code V}/{@code v} represent the type and value of the parameter and argument
@@ -6035,7 +6034,7 @@ public static MethodHandle foldArguments(MethodHandle target, MethodHandle combi
* and values of the {@code target} parameters and arguments that precede and
* follow the folded parameters and arguments starting at {@code pos},
* respectively.
- *
* Note: The resulting adapter is never a {@linkplain MethodHandle#asVarargsCollector
* variable-arity method handle}, even if the original target method handle was.
@@ -6211,7 +6210,7 @@ private static Class> argumentsWithCombinerChecks(int position, boolean filter
* parameters and arguments that are consumed by the {@code test}; and
* {@code B}/{@code b}, those types and values of the {@code target}
* parameters and arguments that are not consumed by the {@code test}.
- *
* Note that the saved arguments ({@code a...} in the pseudocode) cannot
* be modified by execution of the target, and so are passed unchanged
@@ -7808,7 +7807,7 @@ private static void tryFinallyChecks(MethodHandle target, MethodHandle cleanup)
* The cases each drop the {@code selector} value they are given, and take an additional
* {@code String} argument, which is concatenated (using {@link String#concat(String)})
* to a specific constant label string for each case:
- * As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows:
- *
+ * }
*
- * {@code
+ * {@snippet lang="java" :
* Lookup lookup = MethodHandles.lookup(); // in class C
* Lookup lookup2 = lookup.in(D.class);
* MethodHandle mh = lookup2.findStatic(E.class, "m", MT);
- * }
+ * }
* @param refc the class from which the method is accessed
* @param name the name of the method
* @param type the type of the method
@@ -2638,7 +2637,7 @@ public MethodHandle findStatic(Class> refc, String name, MethodType type) thro
* {@code type} arguments.
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
"asList", methodType(List.class, Object[].class));
assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
- * }
+ * }
*
* @param refc the class or interface from which the method is accessed
* @param name the name of the method
@@ -2724,7 +2723,7 @@ private MethodHandle findVirtualForVH(String name, MethodType type) {
* If the returned method handle is invoked, the constructor's class will
* be initialized, if it has not already been initialized.
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -2663,7 +2662,7 @@ public MethodHandle findStatic(Class> refc, String name, MethodType type) thro
MethodHandle MH_newString = publicLookup()
.findConstructor(String.class, MT_newString);
assertEquals("", (String) MH_newString.invokeExact());
- * }
+ * }
* @param refc the class or interface from which the method is accessed
* @param type the type of the method, with the receiver argument omitted, and a void return type
* @return the desired method handle
@@ -2957,7 +2956,7 @@ public Class> accessClass(Class> targetClass) throws IllegalAccessException
* in special circumstances. Use {@link #findConstructor findConstructor}
* to access instance initialization methods in a safe manner.)
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -2740,7 +2739,7 @@ private MethodHandle findVirtualForVH(String name, MethodType type) {
ProcessBuilder pb = (ProcessBuilder)
MH_newProcessBuilder.invoke("x", "y", "z");
assertEquals("[x, y, z]", pb.command().toString());
- * }
+ * }
*
* @param refc the class or interface from which the method is accessed
* @param name the name of the method (which must not be "<init>")
@@ -3277,7 +3276,7 @@ public VarHandle findStaticVarHandle(Class> decl, String name, Class> type)
* the given receiver value will be bound to it.)
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -2988,7 +2987,7 @@ static class Listie extends ArrayList {
} catch (IllegalAccessException ex) { } // OK
Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
- * }
+ * }
* where {@code defc} is either {@code receiver.getClass()} or a super
* type of that class, in which the requested method is accessible
* to the lookup class.
@@ -4588,12 +4587,12 @@ public static VarHandle byteBufferViewVarHandle(Class> viewArrayClass,
* an {@link IllegalArgumentException} instead of invoking the target.
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -3285,7 +3284,7 @@ public VarHandle findStaticVarHandle(Class> decl, String name, Class> type)
MethodHandle mh1 = mh0.bindTo(receiver);
mh1 = mh1.withVarargs(mh0.isVarargsCollector());
return mh1;
- * }
+ * }
* This method throws no reflective or security exceptions.
* @param type the desired target type
* @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
@@ -4832,7 +4831,7 @@ private static void explicitCastArgumentsChecks(MethodHandle target, MethodType
* As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
* incoming arguments which are not mentioned in the reordering array
* may be of any type, as determined only by {@code newType}.
- * {@code
+ * {@snippet lang="java" :
MethodHandle invoker = MethodHandles.invoker(type);
int spreadArgCount = type.parameterCount() - leadingArgCount;
invoker = invoker.asSpreader(Object[].class, spreadArgCount);
return invoker;
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -4848,7 +4847,7 @@ private static void explicitCastArgumentsChecks(MethodHandle target, MethodType
MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
assert(twice.type().equals(intfn1));
assert((int)twice.invokeExact(21) == 42);
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5245,7 +5244,7 @@ private static Class>[] insertArgumentsChecks(MethodHandle target, int insCoun
MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
assertEquals(bigType, d0.type());
assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
- * }
@@ -5306,7 +5305,7 @@ private static int dropArgumentChecks(MethodType oldType, int pos, Class>[] va
* the target's real arguments; if {@code pos} is N
* they will come after.
* @apiNote
- *
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5321,7 +5320,7 @@ private static int dropArgumentChecks(MethodType oldType, int pos, Class>[] va
assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
- * }
@@ -5424,7 +5423,7 @@ private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip,
* @apiNote
* Two method handles whose argument lists are "effectively identical" (i.e., identical in a common prefix) may be
* mutually converted to a common type by two calls to {@code dropArgumentsToMatch}, as follows:
- *
+ * }
* @param target the method handle to adapt
* @param skip number of targets parameters to disregard (they will be unchanged)
* @param newTypes the list of types to match {@code target}'s parameter type list to
@@ -5510,7 +5509,7 @@ public static MethodHandle dropReturn(MethodHandle target) {
* (null or not)
* which do not correspond to argument positions in the target.
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5439,7 +5438,7 @@ private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip,
h2 = dropArgumentsToMatch(h2, 0, h1.type().parameterList(), 0); // lengthen h2
MethodHandle h3 = guardWithTest(h0, h1, h2);
assertEquals("xy", h3.invoke("x", "y", 1, "a", "b", "c"));
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5525,7 +5524,7 @@ public static MethodHandle dropReturn(MethodHandle target) {
assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* T target(P... p, A[i]... a[i], B... b);
* A[i] filter[i](V[i]);
* T adapter(P... p, V[i]... v[i], B... b) {
* return target(p..., filter[i](v[i])..., b...);
* }
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5695,7 +5694,7 @@ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHan
MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
assertEquals("[top, [[up, down, strange], charm], bottom]",
(String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* T target(A...,V,C...);
* V filter(B...);
* T adapter(A... a,B... b,C... c) {
@@ -5728,15 +5727,15 @@ private static void filterArgumentChecks(MethodHandle target, int pos, MethodHan
* filter3(b...);
* return target3(a...,c...);
* }
- * }
+ * }
* If the target method handle consumes no arguments besides than the result
* (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)}
* is equivalent to {@code filterReturnValue(coll, mh)}.
@@ -5804,7 +5803,7 @@ private static MethodType collectArgumentsChecks(MethodHandle target, int pos, M
* The argument type of the filter (if any) must be identical to the
* return type of the target.
* {@code
+ * {@snippet lang="java" :
* mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
* mh = MethodHandles.foldArguments(mh, coll); //step 1
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5815,13 +5814,13 @@ private static MethodType collectArgumentsChecks(MethodHandle target, int pos, M
System.out.println((String) cat.invokeExact("x", "y")); // xy
MethodHandle f0 = filterReturnValue(cat, length);
System.out.println((int) f0.invokeExact("x", "y")); // 2
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* T target(A...);
* V filter(T);
* V adapter(A... a) {
@@ -5842,7 +5841,7 @@ private static MethodType collectArgumentsChecks(MethodHandle target, int pos, M
* T t = target3(a...);
* filter3(t);
* }
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* T target(A...)
* V filter(B... , T)
* V adapter(A... a, B... b) {
* T t = target(a...);
* return filter(b..., t);
* }
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -5956,7 +5955,7 @@ private static void filterReturnValueChecks(MethodType targetType, MethodType fi
MethodHandle catTrace = foldArguments(cat, trace);
// also prints "boo":
assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* // there are N arguments in A...
* T target(V, A[N]..., B...);
* V combiner(A...);
@@ -5981,7 +5980,7 @@ private static void filterReturnValueChecks(MethodType targetType, MethodType fi
* combiner2(a...);
* return target2(a..., b...);
* }
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
@@ -6024,7 +6023,7 @@ public static MethodHandle foldArguments(MethodHandle target, MethodHandle combi
MethodHandle catTrace = foldArguments(cat, 1, trace);
// also prints "jum":
assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* // there are N arguments in A...
* T target(Z..., V, A[N]..., B...);
* V combiner(A...);
@@ -6050,7 +6049,7 @@ public static MethodHandle foldArguments(MethodHandle target, MethodHandle combi
* combiner2(a...);
* return target2(z..., a..., b...);
* }
- * }
+ * }
* Note that the test arguments ({@code a...} in the pseudocode) cannot
* be modified by execution of the test, and so are passed unchanged
* from the caller to the target or fallback as appropriate.
@@ -6274,7 +6273,7 @@ static {@code
+ * {@snippet lang="java" :
* boolean test(A...);
* T target(A...,B...);
* T fallback(A...,B...);
@@ -6221,7 +6220,7 @@ private static Class> argumentsWithCombinerChecks(int position, boolean filter
* else
* return fallback(a..., b...);
* }
- * }
+ * }
* Note that the saved arguments ({@code a...} in the pseudocode) cannot
* be modified by execution of the target, and so are passed unchanged
* from the caller to the handler, if the handler is invoked.
@@ -6556,7 +6555,7 @@ public static MethodHandle throwException(Class> returnType, Class extends T
* Here is pseudocode for the resulting loop handle. As above, {@code V} and {@code v} represent the types
* and values of loop variables; {@code A} and {@code a} represent arguments passed to the whole loop;
* and {@code R} is the common result type of all finalizers as well as of the resulting loop.
- * {@code
+ * {@snippet lang="java" :
* T target(A..., B...);
* T handler(ExType, A...);
* T adapter(A... a, B... b) {
@@ -6284,7 +6283,7 @@ static
+ * }
* Note that the parameter type lists {@code (V...)} and {@code (A...)} have been expanded
* to their full length, even though individual clause functions may neglect to take them all.
* As noted above, missing parameters are filled in as if by {@link #dropArgumentsToMatch(MethodHandle, int, List, int)}.
*
* @apiNote Example:
- * {@code
+ * {@snippet lang="java" :
* V... init...(A...);
* boolean pred...(V..., A...);
* V... step...(V..., A...);
@@ -6572,13 +6571,13 @@ public static MethodHandle throwException(Class> returnType, Class extends T
* }
* }
* }
- * }
+ * }
* The same example, dropping arguments and using combinators:
- * {@code
+ * {@snippet lang="java" :
* // iterative implementation of the factorial function as a loop handle
* static int one(int k) { return 1; }
* static int inc(int i, int acc, int k) { return i + 1; }
@@ -6591,9 +6590,9 @@ public static MethodHandle throwException(Class> returnType, Class extends T
* MethodHandle[] accumulatorClause = new MethodHandle[]{MH_one, MH_mult, MH_pred, MH_fin};
* MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
* assertEquals(120, loop.invoke(5));
- * }
+ * }
* A similar example, using a helper object to hold a loop parameter:
- * {@code
+ * {@snippet lang="java" :
* // simplified implementation of the factorial function as a loop handle
* static int inc(int i) { return i + 1; } // drop acc, k
* static int mult(int i, int acc) { return i * acc; } //drop k
@@ -6607,9 +6606,9 @@ public static MethodHandle throwException(Class> returnType, Class extends T
* MethodHandle[] accumulatorClause = new MethodHandle[]{MH_one, MH_mult, MH_pred, MH_fin};
* MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
* assertEquals(720, loop.invoke(6));
- * }
+ * }
*
* @param clauses an array of arrays (4-tuples) of {@link MethodHandle}s adhering to the rules described above.
*
@@ -6857,7 +6856,7 @@ private static List{@code
+ * {@snippet lang="java" :
* // instance-based implementation of the factorial function as a loop handle
* static class FacLoop {
* final int k;
@@ -6628,7 +6627,7 @@ public static MethodHandle throwException(Class> returnType, Class extends T
* MethodHandle[] accumulatorClause = new MethodHandle[]{MH_one, MH_mult, MH_pred, MH_fin};
* MethodHandle loop = MethodHandles.loop(instanceClause, counterClause, accumulatorClause);
* assertEquals(5040, loop.invoke(7));
- * }
+ * }
*
* @apiNote Example:
- * {@code
+ * {@snippet lang="java" :
* V init(A...);
* boolean pred(V, A...);
* V body(V, A...);
@@ -6868,10 +6867,10 @@ private static List
+ * }
*
*
* @apiNote The implementation of this method can be expressed as follows:
- * {@code
+ * {@snippet lang="java" :
* // implement the zip function for lists as a loop handle
* static List
+ * }
*
* @param init optional initializer, providing the initial value of the loop variable.
* May be {@code null}, implying a default initial value. See above for other constraints.
@@ -6970,7 +6969,7 @@ public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, Metho
* Here is pseudocode for the resulting loop handle. In the code, {@code V}/{@code v} represent the type / value of
* the sole loop variable as well as the result type of the loop; and {@code A}/{@code a}, that of the argument
* passed to the loop.
- * {@code
+ * {@snippet lang="java" :
* MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
* MethodHandle fini = (body.type().returnType() == void.class
* ? null : identity(body.type().returnType()));
@@ -6899,7 +6898,7 @@ private static List
+ * }
*
* @apiNote Example:
- * {@code
+ * {@snippet lang="java" :
* V init(A...);
* boolean pred(V, A...);
* V body(V, A...);
@@ -6981,10 +6980,10 @@ public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, Metho
* } while (pred(v, a...));
* return v;
* }
- * }
+ * }
*
*
* @apiNote The implementation of this method can be expressed as follows:
- * {@code
+ * {@snippet lang="java" :
* // int i = 0; while (i < limit) { ++i; } return i; => limit
* static int zero(int limit) { return 0; }
* static int step(int i, int limit) { return i + 1; }
@@ -6992,18 +6991,18 @@ public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, Metho
* // assume MH_zero, MH_step, and MH_pred are handles to the above methods
* MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred);
* assertEquals(23, loop.invoke(23));
- * }
+ * }
*
* @param init optional initializer, providing the initial value of the loop variable.
* May be {@code null}, implying a default initial value. See above for other constraints.
@@ -7113,7 +7112,7 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* Here is pseudocode for the resulting loop handle. In the code, {@code V}/{@code v} represent the type / value of
* the second loop variable as well as the result type of the loop; and {@code A...}/{@code a...} represent
* arguments passed to the loop.
- * {@code
+ * {@snippet lang="java" :
* MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
* MethodHandle fini = (body.type().returnType() == void.class
* ? null : identity(body.type().returnType()));
* MethodHandle[] clause = { init, body, pred, fini };
* return loop(clause);
* }
- * }
+ * }
*
* @apiNote Example with a fully conformant body method:
- * {@code
+ * {@snippet lang="java" :
* int iterations(A...);
* V init(A...);
* V body(V, int, A...);
@@ -7125,10 +7124,10 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* }
* return v;
* }
- * }
+ * }
*
* @apiNote Example with the simplest possible body method type,
* and passing the number of iterations to the loop invocation:
- * {@code
+ * {@snippet lang="java" :
* // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
* // => a variation on a well known theme
* static String step(String v, int counter, String init) { return "na " + v; }
@@ -7137,11 +7136,11 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* MethodHandle start = MethodHandles.identity(String.class);
* MethodHandle loop = MethodHandles.countedLoop(fit13, start, MH_step);
* assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
- * }
+ * }
*
* @apiNote Example that treats the number of iterations, string to append to, and string to append
* as loop parameters:
- * {@code
+ * {@snippet lang="java" :
* // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
* // => a variation on a well known theme
* static String step(String v, int counter ) { return "na " + v; }
@@ -7150,11 +7149,11 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* MethodHandle start = MethodHandles.dropArguments(MethodHandles.identity(String.class), 0, int.class);
* MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step); // (v, i) -> "na " + v
* assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "Lambdaman!"));
- * }
+ * }
*
* @apiNote Example that illustrates the usage of {@link #dropArgumentsToMatch(MethodHandle, int, List, int)}
* to enforce a loop type:
- * {@code
+ * {@snippet lang="java" :
* // String s = "Lambdaman!", t = "na"; for (int i = 0; i < 13; ++i) { s = t + " " + s; } return s;
* // => a variation on a well known theme
* static String step(String v, int counter, int iterations_, String pre, String start_) { return pre + " " + v; }
@@ -7163,11 +7162,11 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* MethodHandle start = MethodHandles.dropArguments(MethodHandles.identity(String.class), 0, int.class, String.class);
* MethodHandle loop = MethodHandles.countedLoop(count, start, MH_step); // (v, i, _, pre, _) -> pre + " " + v
* assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke(13, "na", "Lambdaman!"));
- * }
+ * }
*
* @apiNote The implementation of this method can be expressed as follows:
- * {@code
+ * {@snippet lang="java" :
* // String s = "Lambdaman!", t = "na"; for (int i = 0; i < 13; ++i) { s = t + " " + s; } return s;
* // => a variation on a well known theme
* static String step(String v, int counter, String pre) { return pre + " " + v; }
@@ -7178,14 +7177,14 @@ private static void whileLoopChecks(MethodHandle init, MethodHandle pred, Method
* MethodHandle body = MethodHandles.dropArgumentsToMatch(MH_step, 2, loopType.parameterList(), 0);
* MethodHandle loop = MethodHandles.countedLoop(count, start, body); // (v, i, pre, _, _) -> pre + " " + v
* assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("na", 13, "Lambdaman!"));
- * }
+ * }
*
* @param iterations a non-{@code null} handle to return the number of iterations this loop should run. The handle's
* result type must be {@code int}. See above for other constraints.
@@ -7268,7 +7267,7 @@ public static MethodHandle countedLoop(MethodHandle iterations, MethodHandle ini
* Here is pseudocode for the resulting loop handle. In the code, {@code V}/{@code v} represent the type / value of
* the second loop variable as well as the result type of the loop; and {@code A...}/{@code a...} represent
* arguments passed to the loop.
- * {@code
+ * {@snippet lang="java" :
* MethodHandle countedLoop(MethodHandle iterations, MethodHandle init, MethodHandle body) {
* return countedLoop(empty(iterations.type()), iterations, init, body);
* }
- * }
+ * }
*
* @apiNote The implementation of this method can be expressed as follows:
- * {@code
+ * {@snippet lang="java" :
* int start(A...);
* int end(A...);
* V init(A...);
@@ -7282,10 +7281,10 @@ public static MethodHandle countedLoop(MethodHandle iterations, MethodHandle ini
* }
* return v;
* }
- * }
+ * }
*
* @param start a non-{@code null} handle to return the start value of the loop counter, which must be {@code int}.
* See above for other constraints.
@@ -7470,7 +7469,7 @@ private static void countedLoopChecks(MethodHandle start, MethodHandle end, Meth
* Here is pseudocode for the resulting loop handle. In the code, {@code V}/{@code v} represent the type / value of
* the loop variable as well as the result type of the loop; {@code T}/{@code t}, that of the elements of the
* structure the loop iterates over, and {@code A...}/{@code a...} represent arguments passed to the loop.
- * {@code
+ * {@snippet lang="java" :
* MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
* MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, int.class, int.class);
* // assume MH_increment and MH_predicate are handles to implementation-internal methods with
@@ -7307,7 +7306,7 @@ public static MethodHandle countedLoop(MethodHandle iterations, MethodHandle ini
* indexVar = { start, incr }; // i = start(); i = i + 1
* return loop(loopLimit, bodyClause, indexVar);
* }
- * }
+ * }
*
* @apiNote Example:
- * {@code
+ * {@snippet lang="java" :
* Iterator
+ * }
*
* @apiNote The implementation of this method can be expressed approximately as follows:
- * {@code
+ * {@snippet lang="java" :
* // get an iterator from a list
* static List
+ * }
*
* @param iterator an optional handle to return the iterator to start the loop.
* If non-{@code null}, the handle must return {@link java.util.Iterator} or a subtype.
@@ -7686,7 +7685,7 @@ static MethodHandle swapArguments(MethodHandle mh, int i, int j) {
* the {@code try/finally} construct; {@code A}/{@code a}, the types and values of arguments to the resulting
* handle consumed by the cleanup; and {@code B}/{@code b}, those of arguments to the resulting handle discarded by
* the cleanup.
- * {@code
+ * {@snippet lang="java" :
* MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
* // assume MH_next, MH_hasNext, MH_startIter are handles to methods of Iterator/Iterable
* Class> returnType = body.type().returnType();
@@ -7520,7 +7519,7 @@ private static void countedLoopChecks(MethodHandle start, MethodHandle end, Meth
* bodyClause = { init, filterArguments(step, 0, nextVal) }; // v = body(v, t, a)
* return loop(iterVar, bodyClause);
* }
- * }
+ * }
* {@code
+ * {@snippet lang="java" :
* V target(A..., B...);
* V cleanup(Throwable, V, A...);
* V adapter(A... a, B... b) {
@@ -7702,7 +7701,7 @@ static MethodHandle swapArguments(MethodHandle mh, int i, int j) {
* }
* return result;
* }
- * }
+ * }
*
* @param fallback the fallback method handle that is called when the selector is not
* within the range {@code [0, N)}.
@@ -7887,17 +7886,17 @@ private static MethodType tableSwitchChecks(MethodHandle defaultCase, MethodHand
* the alignment constraint (in bytes) for the resulting var handle is given by {@code alignmentBytes}.
*
* {@code
+ * {@snippet lang="java" :
* MethodHandles.Lookup lookup = MethodHandles.lookup();
* MethodHandle caseMh = lookup.findVirtual(String.class, "concat",
* MethodType.methodType(String.class, String.class));
@@ -7828,7 +7827,7 @@ private static void tryFinallyChecks(MethodHandle target, MethodHandle cleanup)
* assertEquals("case 0: data", (String) mhSwitch.invokeExact(0, "data"));
* assertEquals("case 1: data", (String) mhSwitch.invokeExact(1, "data"));
* assertEquals("default: data", (String) mhSwitch.invokeExact(2, "data"));
- * }
+ * }
* To access the member layout named {@code value}, we can construct a memory segment view var handle as follows:
- * {@code
+ * {@snippet lang="java" :
* GroupLayout seq = java.lang.foreign.MemoryLayout.structLayout(
* MemoryLayout.paddingLayout(32),
* ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
* );
- * }
+ * }
*
* @apiNote The resulting var handle features certain access mode restrictions,
* which are common to all memory segment view var handles. A memory segment view var handle is associated
{@code
+ * {@snippet lang="java" :
* VarHandle handle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
* handle = MethodHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
- * }