Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
47209 views
/*1* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @summary example code used in javadoc for java.lang.invoke API25* @compile JavaDocExamplesTest.java26* @run testng/othervm test.java.lang.invoke.JavaDocExamplesTest27*/2829package test.java.lang.invoke;3031import java.lang.invoke.*;32import static java.lang.invoke.MethodHandles.*;33import static java.lang.invoke.MethodType.*;3435import java.util.*;3637import org.testng.*;38import static org.testng.AssertJUnit.*;39import org.testng.annotations.*;4041/**42* @author jrose43*/44public class JavaDocExamplesTest {45/** Wrapper for running the TestNG tests in this module.46* Put TestNG on the classpath!47*/48public static void main(String... ignore) throws Throwable {49new JavaDocExamplesTest().run();50}5152public void run() throws Throwable {53testMisc();54testFindStatic();55testFindConstructor();56testFindVirtual();57testFindSpecial();58testPermuteArguments();59testDropArguments();60testFilterArguments();61testFoldArguments();62testFoldArguments2();63testMethodHandlesSummary();64testAsSpreader();65testAsCollector();66testAsVarargsCollector();67testAsFixedArity();68testAsTypeCornerCases();69testMutableCallSite();70}71// How much output?72static final Class<?> THIS_CLASS = JavaDocExamplesTest.class;73static int verbosity = Integer.getInteger(THIS_CLASS.getSimpleName()+".verbosity", 0);747576{}77static final private Lookup LOOKUP = lookup();78// static final private MethodHandle CONCAT_1 = LOOKUP.findVirtual(String.class,79// "concat", methodType(String.class, String.class));80// static final private MethodHandle HASHCODE_1 = LOOKUP.findVirtual(Object.class,81// "hashCode", methodType(int.class));8283// form required if ReflectiveOperationException is intercepted:84static final private MethodHandle CONCAT_2, HASHCODE_2, ADD_2, SUB_2;85static {86try {87Class<?> THIS_CLASS = LOOKUP.lookupClass();88CONCAT_2 = LOOKUP.findVirtual(String.class,89"concat", methodType(String.class, String.class));90HASHCODE_2 = LOOKUP.findVirtual(Object.class,91"hashCode", methodType(int.class));92ADD_2 = LOOKUP.findStatic(THIS_CLASS, "add", methodType(int.class, int.class, int.class));93SUB_2 = LOOKUP.findStatic(THIS_CLASS, "sub", methodType(int.class, int.class, int.class));94} catch (ReflectiveOperationException ex) {95throw new RuntimeException(ex);96}97}98static int add(int x, int y) { return x + y; }99static int sub(int x, int y) { return x - y; }100101{}102103@Test public void testMisc() throws Throwable {104// Extra tests, not from javadoc:105{}106MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class,107"concat", methodType(String.class, String.class));108MethodHandle HASHCODE_3 = LOOKUP.findVirtual(Object.class,109"hashCode", methodType(int.class));110//assertEquals("xy", (String) CONCAT_1.invokeExact("x", "y"));111assertEquals("xy", (String) CONCAT_2.invokeExact("x", "y"));112assertEquals("xy", (String) CONCAT_3.invokeExact("x", "y"));113//assertEquals("xy".hashCode(), (int) HASHCODE_1.invokeExact((Object)"xy"));114assertEquals("xy".hashCode(), (int) HASHCODE_2.invokeExact((Object)"xy"));115assertEquals("xy".hashCode(), (int) HASHCODE_3.invokeExact((Object)"xy"));116{}117}118119@Test public void testFindStatic() throws Throwable {120{}121MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,122"asList", methodType(List.class, Object[].class));123assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());124{}125}126127@Test public void testFindVirtual() throws Throwable {128{}129MethodHandle MH_concat = publicLookup().findVirtual(String.class,130"concat", methodType(String.class, String.class));131MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,132"hashCode", methodType(int.class));133MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,134"hashCode", methodType(int.class));135assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));136assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));137assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));138// interface method:139MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,140"subSequence", methodType(CharSequence.class, int.class, int.class));141assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());142// constructor "internal method" must be accessed differently:143MethodType MT_newString = methodType(void.class); //()V for new String()144try { assertEquals("impossible", lookup()145.findVirtual(String.class, "<init>", MT_newString));146} catch (NoSuchMethodException ex) { } // OK147MethodHandle MH_newString = publicLookup()148.findConstructor(String.class, MT_newString);149assertEquals("", (String) MH_newString.invokeExact());150{}151}152153@Test public void testFindConstructor() throws Throwable {154{}155MethodHandle MH_newArrayList = publicLookup().findConstructor(156ArrayList.class, methodType(void.class, Collection.class));157Collection orig = Arrays.asList("x", "y");158Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);159assert(orig != copy);160assertEquals(orig, copy);161// a variable-arity constructor:162MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(163ProcessBuilder.class, methodType(void.class, String[].class));164ProcessBuilder pb = (ProcessBuilder)165MH_newProcessBuilder.invoke("x", "y", "z");166assertEquals("[x, y, z]", pb.command().toString());167{}168}169170// for testFindSpecial171{}172static class Listie extends ArrayList {173public String toString() { return "[wee Listie]"; }174static Lookup lookup() { return MethodHandles.lookup(); }175}176{}177178@Test public void testFindSpecial() throws Throwable {179{}180// no access to constructor via invokeSpecial:181MethodHandle MH_newListie = Listie.lookup()182.findConstructor(Listie.class, methodType(void.class));183Listie l = (Listie) MH_newListie.invokeExact();184try { assertEquals("impossible", Listie.lookup().findSpecial(185Listie.class, "<init>", methodType(void.class), Listie.class));186} catch (NoSuchMethodException ex) { } // OK187// access to super and self methods via invokeSpecial:188MethodHandle MH_super = Listie.lookup().findSpecial(189ArrayList.class, "toString" , methodType(String.class), Listie.class);190MethodHandle MH_this = Listie.lookup().findSpecial(191Listie.class, "toString" , methodType(String.class), Listie.class);192MethodHandle MH_duper = Listie.lookup().findSpecial(193Object.class, "toString" , methodType(String.class), Listie.class);194assertEquals("[]", (String) MH_super.invokeExact(l));195assertEquals(""+l, (String) MH_this.invokeExact(l));196assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method197try { assertEquals("inaccessible", Listie.lookup().findSpecial(198String.class, "toString", methodType(String.class), Listie.class));199} catch (IllegalAccessException ex) { } // OK200Listie subl = new Listie() { public String toString() { return "[subclass]"; } };201assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method202{}203}204205@Test public void testPermuteArguments() throws Throwable {206{{207{} /// JAVADOC208MethodType intfn1 = methodType(int.class, int.class);209MethodType intfn2 = methodType(int.class, int.class, int.class);210MethodHandle sub = SUB_2;// ... {int x, int y => x-y} ...;211assert(sub.type().equals(intfn2));212MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);213MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);214assert((int)rsub.invokeExact(1, 100) == 99);215MethodHandle add = ADD_2;// ... {int x, int y => x+y} ...;216assert(add.type().equals(intfn2));217MethodHandle twice = permuteArguments(add, intfn1, 0, 0);218assert(twice.type().equals(intfn1));219assert((int)twice.invokeExact(21) == 42);220}}221{{222{} /// JAVADOC223MethodHandle cat = lookup().findVirtual(String.class,224"concat", methodType(String.class, String.class));225assertEquals("xy", (String) cat.invokeExact("x", "y"));226MethodHandle d0 = dropArguments(cat, 0, String.class);227assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));228MethodHandle d1 = dropArguments(cat, 1, String.class);229assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));230MethodHandle d2 = dropArguments(cat, 2, String.class);231assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));232MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);233assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));234}}235}236237@Test public void testDropArguments() throws Throwable {238{{239{} /// JAVADOC240MethodHandle cat = lookup().findVirtual(String.class,241"concat", methodType(String.class, String.class));242assertEquals("xy", (String) cat.invokeExact("x", "y"));243MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);244MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));245assertEquals(bigType, d0.type());246assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));247}}248{{249{} /// JAVADOC250MethodHandle cat = lookup().findVirtual(String.class,251"concat", methodType(String.class, String.class));252assertEquals("xy", (String) cat.invokeExact("x", "y"));253MethodHandle d0 = dropArguments(cat, 0, String.class);254assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));255MethodHandle d1 = dropArguments(cat, 1, String.class);256assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));257MethodHandle d2 = dropArguments(cat, 2, String.class);258assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));259MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);260assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));261}}262}263264@Test public void testFilterArguments() throws Throwable {265{{266{} /// JAVADOC267MethodHandle cat = lookup().findVirtual(String.class,268"concat", methodType(String.class, String.class));269MethodHandle upcase = lookup().findVirtual(String.class,270"toUpperCase", methodType(String.class));271assertEquals("xy", (String) cat.invokeExact("x", "y"));272MethodHandle f0 = filterArguments(cat, 0, upcase);273assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy274MethodHandle f1 = filterArguments(cat, 1, upcase);275assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY276MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);277assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY278}}279}280281@Test public void testCollectArguments() throws Throwable {282{{283{} /// JAVADOC284MethodHandle deepToString = publicLookup()285.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));286MethodHandle ts1 = deepToString.asCollector(String[].class, 1);287assertEquals("[strange]", (String) ts1.invokeExact("strange"));288MethodHandle ts2 = deepToString.asCollector(String[].class, 2);289assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));290MethodHandle ts3 = deepToString.asCollector(String[].class, 3);291MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);292assertEquals("[top, [up, down], strange]",293(String) ts3_ts2.invokeExact("top", "up", "down", "strange"));294MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);295assertEquals("[top, [up, down], [strange]]",296(String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));297MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);298assertEquals("[top, [[up, down, strange], charm], bottom]",299(String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));300}}301}302303@Test public void testFoldArguments() throws Throwable {304{{305{} /// JAVADOC306MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,307"println", methodType(void.class, String.class))308.bindTo(System.out);309MethodHandle cat = lookup().findVirtual(String.class,310"concat", methodType(String.class, String.class));311assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));312MethodHandle catTrace = foldArguments(cat, trace);313// also prints "boo":314assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));315}}316}317318static void assertEquals(Object exp, Object act) {319if (verbosity > 0)320System.out.println("result: "+act);321Assert.assertEquals(exp, act);322}323324@Test public void testMethodHandlesSummary() throws Throwable {325{{326{} /// JAVADOC327Object x, y; String s; int i;328MethodType mt; MethodHandle mh;329MethodHandles.Lookup lookup = MethodHandles.lookup();330// mt is (char,char)String331mt = MethodType.methodType(String.class, char.class, char.class);332mh = lookup.findVirtual(String.class, "replace", mt);333s = (String) mh.invokeExact("daddy",'d','n');334// invokeExact(Ljava/lang/String;CC)Ljava/lang/String;335assertEquals(s, "nanny");336// weakly typed invocation (using MHs.invoke)337s = (String) mh.invokeWithArguments("sappy", 'p', 'v');338assertEquals(s, "savvy");339// mt is (Object[])List340mt = MethodType.methodType(java.util.List.class, Object[].class);341mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);342assert(mh.isVarargsCollector());343x = mh.invoke("one", "two");344// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;345assertEquals(x, java.util.Arrays.asList("one","two"));346// mt is (Object,Object,Object)Object347mt = MethodType.genericMethodType(3);348mh = mh.asType(mt);349x = mh.invokeExact((Object)1, (Object)2, (Object)3);350// invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;351assertEquals(x, java.util.Arrays.asList(1,2,3));352// mt is ()int353mt = MethodType.methodType(int.class);354mh = lookup.findVirtual(java.util.List.class, "size", mt);355i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));356// invokeExact(Ljava/util/List;)I357assert(i == 3);358mt = MethodType.methodType(void.class, String.class);359mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);360mh.invokeExact(System.out, "Hello, world.");361// invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V362{}363}}364}365366@Test public void testAsSpreader() throws Throwable {367{{368{} /// JAVADOC369MethodHandle equals = publicLookup()370.findVirtual(String.class, "equals", methodType(boolean.class, Object.class));371assert( (boolean) equals.invokeExact("me", (Object)"me"));372assert(!(boolean) equals.invokeExact("me", (Object)"thee"));373// spread both arguments from a 2-array:374MethodHandle eq2 = equals.asSpreader(Object[].class, 2);375assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));376assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));377// try to spread from anything but a 2-array:378for (int n = 0; n <= 10; n++) {379Object[] badArityArgs = (n == 2 ? null : new Object[n]);380try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }381catch (IllegalArgumentException ex) { } // OK382}383// spread both arguments from a String array:384MethodHandle eq2s = equals.asSpreader(String[].class, 2);385assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));386assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));387// spread second arguments from a 1-array:388MethodHandle eq1 = equals.asSpreader(Object[].class, 1);389assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));390assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));391// spread no arguments from a 0-array or null:392MethodHandle eq0 = equals.asSpreader(Object[].class, 0);393assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));394assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));395// asSpreader and asCollector are approximate inverses:396for (int n = 0; n <= 2; n++) {397for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {398MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);399assert( (boolean) equals2.invokeWithArguments("me", "me"));400assert(!(boolean) equals2.invokeWithArguments("me", "thee"));401}402}403MethodHandle caToString = publicLookup()404.findStatic(Arrays.class, "toString", methodType(String.class, char[].class));405assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));406MethodHandle caString3 = caToString.asCollector(char[].class, 3);407assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));408MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);409assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));410}}411}412413@Test public void testAsCollector() throws Throwable {414{{415{} /// JAVADOC416MethodHandle deepToString = publicLookup()417.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));418assertEquals("[won]", (String) deepToString.invokeExact(new Object[]{"won"}));419MethodHandle ts1 = deepToString.asCollector(Object[].class, 1);420assertEquals(methodType(String.class, Object.class), ts1.type());421//assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"})); //FAIL422assertEquals("[[won]]", (String) ts1.invokeExact((Object) new Object[]{"won"}));423// arrayType can be a subtype of Object[]424MethodHandle ts2 = deepToString.asCollector(String[].class, 2);425assertEquals(methodType(String.class, String.class, String.class), ts2.type());426assertEquals("[two, too]", (String) ts2.invokeExact("two", "too"));427MethodHandle ts0 = deepToString.asCollector(Object[].class, 0);428assertEquals("[]", (String) ts0.invokeExact());429// collectors can be nested, Lisp-style430MethodHandle ts22 = deepToString.asCollector(Object[].class, 3).asCollector(String[].class, 2);431assertEquals("[A, B, [C, D]]", ((String) ts22.invokeExact((Object)'A', (Object)"B", "C", "D")));432// arrayType can be any primitive array type433MethodHandle bytesToString = publicLookup()434.findStatic(Arrays.class, "toString", methodType(String.class, byte[].class))435.asCollector(byte[].class, 3);436assertEquals("[1, 2, 3]", (String) bytesToString.invokeExact((byte)1, (byte)2, (byte)3));437MethodHandle longsToString = publicLookup()438.findStatic(Arrays.class, "toString", methodType(String.class, long[].class))439.asCollector(long[].class, 1);440assertEquals("[123]", (String) longsToString.invokeExact((long)123));441}}442}443444@SuppressWarnings("rawtypes")445@Test public void testAsVarargsCollector() throws Throwable {446{{447{} /// JAVADOC448MethodHandle deepToString = publicLookup()449.findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));450MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);451assertEquals("[won]", (String) ts1.invokeExact( new Object[]{"won"}));452assertEquals("[won]", (String) ts1.invoke( new Object[]{"won"}));453assertEquals("[won]", (String) ts1.invoke( "won" ));454assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));455// findStatic of Arrays.asList(...) produces a variable arity method handle:456MethodHandle asList = publicLookup()457.findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));458assertEquals(methodType(List.class, Object[].class), asList.type());459assert(asList.isVarargsCollector());460assertEquals("[]", asList.invoke().toString());461assertEquals("[1]", asList.invoke(1).toString());462assertEquals("[two, too]", asList.invoke("two", "too").toString());463String[] argv = { "three", "thee", "tee" };464assertEquals("[three, thee, tee]", asList.invoke(argv).toString());465assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());466List ls = (List) asList.invoke((Object)argv);467assertEquals(1, ls.size());468assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));469}}470}471472@Test public void testAsFixedArity() throws Throwable {473{{474{} /// JAVADOC475MethodHandle asListVar = publicLookup()476.findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))477.asVarargsCollector(Object[].class);478MethodHandle asListFix = asListVar.asFixedArity();479assertEquals("[1]", asListVar.invoke(1).toString());480Exception caught = null;481try { asListFix.invoke((Object)1); }482catch (Exception ex) { caught = ex; }483assert(caught instanceof ClassCastException);484assertEquals("[two, too]", asListVar.invoke("two", "too").toString());485try { asListFix.invoke("two", "too"); }486catch (Exception ex) { caught = ex; }487assert(caught instanceof WrongMethodTypeException);488Object[] argv = { "three", "thee", "tee" };489assertEquals("[three, thee, tee]", asListVar.invoke(argv).toString());490assertEquals("[three, thee, tee]", asListFix.invoke(argv).toString());491assertEquals(1, ((List) asListVar.invoke((Object)argv)).size());492assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());493}}494}495496@Test public void testAsTypeCornerCases() throws Throwable {497{{498{} /// JAVADOC499MethodHandle i2s = publicLookup()500.findVirtual(Integer.class, "toString", methodType(String.class));501i2s = i2s.asType(i2s.type().unwrap());502MethodHandle l2s = publicLookup()503.findVirtual(Long.class, "toString", methodType(String.class));504l2s = l2s.asType(l2s.type().unwrap());505506Exception caught = null;507try { i2s.asType(methodType(String.class, String.class)); }508catch (Exception ex) { caught = ex; }509assert(caught instanceof WrongMethodTypeException);510511i2s.asType(methodType(String.class, byte.class));512i2s.asType(methodType(String.class, Byte.class));513i2s.asType(methodType(String.class, Character.class));514i2s.asType(methodType(String.class, Integer.class));515l2s.asType(methodType(String.class, byte.class));516l2s.asType(methodType(String.class, Byte.class));517l2s.asType(methodType(String.class, Character.class));518l2s.asType(methodType(String.class, Integer.class));519l2s.asType(methodType(String.class, Long.class));520521caught = null;522try { i2s.asType(methodType(String.class, Long.class)); }523catch (Exception ex) { caught = ex; }524assert(caught instanceof WrongMethodTypeException);525526MethodHandle i2sGen = i2s.asType(methodType(String.class, Object.class));527MethodHandle l2sGen = l2s.asType(methodType(String.class, Object.class));528529i2sGen.invoke(42); // int -> Integer -> Object -> Integer -> int530i2sGen.invoke((byte)4); // byte -> Byte -> Object -> Byte -> byte -> int531l2sGen.invoke(42); // int -> Integer -> Object -> Integer -> int532l2sGen.invoke((byte)4); // byte -> Byte -> Object -> Byte -> byte -> int533l2sGen.invoke(0x420000000L);534535caught = null;536try { i2sGen.invoke(0x420000000L); } // long -> Long -> Object -> Integer CCE537catch (Exception ex) { caught = ex; }538assert(caught instanceof ClassCastException);539540caught = null;541try { i2sGen.invoke("asdf"); } // String -> Object -> Integer CCE542catch (Exception ex) { caught = ex; }543assert(caught instanceof ClassCastException);544{}545}}546}547548@Test public void testMutableCallSite() throws Throwable {549{{550{} /// JAVADOC551MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));552MethodHandle MH_name = name.dynamicInvoker();553MethodType MT_str1 = MethodType.methodType(String.class);554MethodHandle MH_upcase = MethodHandles.lookup()555.findVirtual(String.class, "toUpperCase", MT_str1);556MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);557name.setTarget(MethodHandles.constant(String.class, "Rocky"));558assertEquals("ROCKY", (String) worker1.invokeExact());559name.setTarget(MethodHandles.constant(String.class, "Fred"));560assertEquals("FRED", (String) worker1.invokeExact());561// (mutation can be continued indefinitely)562/*563* </pre></blockquote>564* <p>565* The same call site may be used in several places at once.566* <blockquote><pre>567*/568MethodType MT_str2 = MethodType.methodType(String.class, String.class);569MethodHandle MH_cat = lookup().findVirtual(String.class,570"concat", methodType(String.class, String.class));571MethodHandle MH_dear = MethodHandles.insertArguments(MH_cat, 1, ", dear?");572MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);573assertEquals("Fred, dear?", (String) worker2.invokeExact());574name.setTarget(MethodHandles.constant(String.class, "Wilma"));575assertEquals("WILMA", (String) worker1.invokeExact());576assertEquals("Wilma, dear?", (String) worker2.invokeExact());577{}578}}579}580581@Test public void testSwitchPoint() throws Throwable {582{{583{} /// JAVADOC584MethodHandle MH_strcat = MethodHandles.lookup()585.findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));586SwitchPoint spt = new SwitchPoint();587assert(!spt.hasBeenInvalidated());588// the following steps may be repeated to re-use the same switch point:589MethodHandle worker1 = MH_strcat;590MethodHandle worker2 = MethodHandles.permuteArguments(MH_strcat, MH_strcat.type(), 1, 0);591MethodHandle worker = spt.guardWithTest(worker1, worker2);592assertEquals("method", (String) worker.invokeExact("met", "hod"));593SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });594assert(spt.hasBeenInvalidated());595assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));596{}597}}598}599600@Test public void testFoldArguments2() throws Throwable {601{{602{} /// JAVADOC603// argument-based dispatch for methods of the form boolean x.___(y: String)604Lookup lookup = publicLookup();605// first, a tracing hack:606MethodHandle println = lookup.findVirtual(java.io.PrintStream.class, "println", methodType(void.class, String.class));607MethodHandle arrayToString = lookup.findStatic(Arrays.class, "toString", methodType(String.class, Object[].class));608MethodHandle concat = lookup.findVirtual(String.class, "concat", methodType(String.class, String.class));609MethodHandle arrayToString_DIS = filterReturnValue(arrayToString, concat.bindTo("DIS:"));610MethodHandle arrayToString_INV = filterReturnValue(arrayToString, concat.bindTo("INV:"));611MethodHandle printArgs_DIS = filterReturnValue(arrayToString_DIS, println.bindTo(System.out)).asVarargsCollector(Object[].class);612MethodHandle printArgs_INV = filterReturnValue(arrayToString_INV, println.bindTo(System.out)).asVarargsCollector(Object[].class);613// metaobject protocol:614MethodType mtype = methodType(boolean.class, String.class);615MethodHandle findVirtual = lookup.findVirtual(Lookup.class,616"findVirtual", methodType(MethodHandle.class, Class.class, String.class, MethodType.class));617MethodHandle getClass = lookup.findVirtual(Object.class,618"getClass", methodType(Class.class));619MethodHandle dispatch = findVirtual;620dispatch = filterArguments(dispatch, 1, getClass);621dispatch = insertArguments(dispatch, 3, mtype);622dispatch = dispatch.bindTo(lookup);623assertEquals(methodType(MethodHandle.class, Object.class, String.class), dispatch.type());624MethodHandle invoker = invoker(mtype.insertParameterTypes(0, Object.class));625// wrap tracing around the dispatch and invoke steps:626dispatch = foldArguments(dispatch, printArgs_DIS.asType(dispatch.type().changeReturnType(void.class)));627invoker = foldArguments(invoker, printArgs_INV.asType(invoker.type().changeReturnType(void.class)));628invoker = dropArguments(invoker, 2, String.class); // ignore selector629// compose the dispatcher and the invoker:630MethodHandle invokeDispatched = foldArguments(invoker, dispatch);631Object x = "football", y = new java.util.Scanner("bar");632assert( (boolean) invokeDispatched.invokeExact(x, "startsWith", "foo"));633assert(!(boolean) invokeDispatched.invokeExact(x, "startsWith", "#"));634assert( (boolean) invokeDispatched.invokeExact(x, "endsWith", "all"));635assert(!(boolean) invokeDispatched.invokeExact(x, "endsWith", "foo"));636assert( (boolean) invokeDispatched.invokeExact(y, "hasNext", "[abc]+[rst]"));637assert(!(boolean) invokeDispatched.invokeExact(y, "hasNext", "[123]+[789]"));638}}639}640641/* ---- TEMPLATE ----642@Test public void testFoo() throws Throwable {643{{644{} /// JAVADOC645{}646}}647}648*/649}650651652