src/share/classes/java/lang/invoke/MethodHandle.java
Print this page
*** 249,259 ****
* receiver type. Such a method handle simulates the effect of
* an {@code invokespecial} instruction to the same method.
*
* <h3>Usage examples</h3>
* Here are some examples of usage:
! * <p><blockquote><pre>
Object x, y; String s; int i;
MethodType mt; MethodHandle mh;
MethodHandles.Lookup lookup = MethodHandles.lookup();
// mt is (char,char)String
mt = MethodType.methodType(String.class, char.class, char.class);
--- 249,259 ----
* receiver type. Such a method handle simulates the effect of
* an {@code invokespecial} instruction to the same method.
*
* <h3>Usage examples</h3>
* Here are some examples of usage:
! * <p><blockquote><pre>{@code
Object x, y; String s; int i;
MethodType mt; MethodHandle mh;
MethodHandles.Lookup lookup = MethodHandles.lookup();
// mt is (char,char)String
mt = MethodType.methodType(String.class, char.class, char.class);
*** 285,295 ****
assert(i == 3);
mt = MethodType.methodType(void.class, String.class);
mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
mh.invokeExact(System.out, "Hello, world.");
// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
! * </pre></blockquote>
* 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.
* In these examples, the helper method {@code assertEquals} is assumed to
* be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
--- 285,295 ----
assert(i == 3);
mt = MethodType.methodType(void.class, String.class);
mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
mh.invokeExact(System.out, "Hello, world.");
// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
! * }</pre></blockquote>
* 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.
* In these examples, the helper method {@code assertEquals} is assumed to
* be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
*** 752,762 ****
* contains exactly enough elements to provide a correct argument count
* to the target method handle.
* (The array may also be null when zero elements are required.)
* <p>
* Here are some simple examples of array-spreading method handles:
! * <blockquote><pre>
MethodHandle equals = publicLookup()
.findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
assert( (boolean) equals.invokeExact("me", (Object)"me"));
assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
// spread both arguments from a 2-array:
--- 752,762 ----
* contains exactly enough elements to provide a correct argument count
* to the target method handle.
* (The array may also be null when zero elements are required.)
* <p>
* Here are some simple examples of array-spreading method handles:
! * <blockquote><pre>{@code
MethodHandle equals = publicLookup()
.findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
assert( (boolean) equals.invokeExact("me", (Object)"me"));
assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
// spread both arguments from a 2-array:
*** 788,798 ****
assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
MethodHandle caString3 = caToString.asCollector(char[].class, 3);
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()));
! * </pre></blockquote>
* @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,
* before calling the original method handle
* @throws NullPointerException if {@code arrayType} is a null reference
--- 788,798 ----
assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
MethodHandle caString3 = caToString.asCollector(char[].class, 3);
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()));
! * }</pre></blockquote>
* @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,
* before calling the original method handle
* @throws NullPointerException if {@code arrayType} is a null reference
*** 876,886 ****
* <p>
* In order to create a collecting adapter which is not restricted to a particular
* number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
* <p>
* Here are some examples of array-collecting method handles:
! * <blockquote><pre>
MethodHandle deepToString = publicLookup()
.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
assertEquals(methodType(String.class, Object.class), ts1.type());
--- 876,886 ----
* <p>
* In order to create a collecting adapter which is not restricted to a particular
* number of collected arguments, use {@link #asVarargsCollector asVarargsCollector} instead.
* <p>
* Here are some examples of array-collecting method handles:
! * <blockquote><pre>{@code
MethodHandle deepToString = publicLookup()
.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));
MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);
assertEquals(methodType(String.class, Object.class), ts1.type());
*** 902,912 ****
assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));
MethodHandle longsToString = publicLookup()
.findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
.asCollector(long[].class, 1);
assertEquals("[123]", (String) longsToString.invokeExact((long)123));
! * </pre></blockquote>
* @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
* @param arrayLength the number of arguments to collect into a new array argument
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* @throws NullPointerException if {@code arrayType} is a null reference
--- 902,912 ----
assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));
MethodHandle longsToString = publicLookup()
.findStatic(Arrays.class, "toString", methodType(String.class, long[].class))
.asCollector(long[].class, 1);
assertEquals("[123]", (String) longsToString.invokeExact((long)123));
! * }</pre></blockquote>
* @param arrayType often {@code Object[]}, the type of the array argument which will collect the arguments
* @param arrayLength the number of arguments to collect into a new array argument
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* @throws NullPointerException if {@code arrayType} is a null reference
*** 1039,1049 ****
* Calling {@code asVarargsCollector} on a method handle which is already
* of variable arity will produce a method handle with the same type and behavior.
* It may (or may not) return the original variable arity method handle.
* <p>
* Here is an example, of a list-making variable arity method handle:
! * <blockquote><pre>
MethodHandle deepToString = publicLookup()
.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
--- 1039,1049 ----
* Calling {@code asVarargsCollector} on a method handle which is already
* of variable arity will produce a method handle with the same type and behavior.
* It may (or may not) return the original variable arity method handle.
* <p>
* Here is an example, of a list-making variable arity method handle:
! * <blockquote><pre>{@code
MethodHandle deepToString = publicLookup()
.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));
assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));
*** 1061,1071 ****
assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
List ls = (List) asList.invoke((Object)argv);
assertEquals(1, ls.size());
assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
! * </pre></blockquote>
* <p style="font-size:smaller;">
* <em>Discussion:</em>
* These rules are designed as a dynamically-typed variation
* of the Java rules for variable arity methods.
* In both cases, callers to a variable arity method or method handle
--- 1061,1071 ----
assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
List ls = (List) asList.invoke((Object)argv);
assertEquals(1, ls.size());
assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
! * }</pre></blockquote>
* <p style="font-size:smaller;">
* <em>Discussion:</em>
* These rules are designed as a dynamically-typed variation
* of the Java rules for variable arity methods.
* In both cases, callers to a variable arity method or method handle
*** 1132,1142 ****
* will be false.
* The fixed-arity method handle may (or may not) be the
* a previous argument to {@code asVarargsCollector}.
* <p>
* Here is an example, of a list-making variable arity method handle:
! * <blockquote><pre>
MethodHandle asListVar = publicLookup()
.findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
.asVarargsCollector(Object[].class);
MethodHandle asListFix = asListVar.asFixedArity();
assertEquals("[1]", asListVar.invoke(1).toString());
--- 1132,1142 ----
* will be false.
* The fixed-arity method handle may (or may not) be the
* a previous argument to {@code asVarargsCollector}.
* <p>
* Here is an example, of a list-making variable arity method handle:
! * <blockquote><pre>{@code
MethodHandle asListVar = publicLookup()
.findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
.asVarargsCollector(Object[].class);
MethodHandle asListFix = asListVar.asFixedArity();
assertEquals("[1]", asListVar.invoke(1).toString());
*** 1151,1161 ****
Object[] argv = { "three", "thee", "tee" };
assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
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());
! * </pre></blockquote>
*
* @return a new method handle which accepts only a fixed number of arguments
* @see #asVarargsCollector
* @see #isVarargsCollector
*/
--- 1151,1161 ----
Object[] argv = { "three", "thee", "tee" };
assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());
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());
! * }</pre></blockquote>
*
* @return a new method handle which accepts only a fixed number of arguments
* @see #asVarargsCollector
* @see #isVarargsCollector
*/