1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandle; 18*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandleInfo; 19*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles; 20*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles.Lookup; 21*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodType; 22*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.WrongMethodTypeException; 23*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Constructor; 24*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Field; 25*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException; 26*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 27*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Proxy; 28*795d594fSAndroid Build Coastguard Worker import java.nio.charset.Charset; 29*795d594fSAndroid Build Coastguard Worker import java.nio.charset.StandardCharsets; 30*795d594fSAndroid Build Coastguard Worker import java.util.AbstractList; 31*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList; 32*795d594fSAndroid Build Coastguard Worker import java.util.Arrays; 33*795d594fSAndroid Build Coastguard Worker import java.util.Collections; 34*795d594fSAndroid Build Coastguard Worker import java.util.List; 35*795d594fSAndroid Build Coastguard Worker import java.util.function.Consumer; 36*795d594fSAndroid Build Coastguard Worker import other.Chatty; 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker public class Main { 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker public static class A { A()41*795d594fSAndroid Build Coastguard Worker public A() {} 42*795d594fSAndroid Build Coastguard Worker foo()43*795d594fSAndroid Build Coastguard Worker public void foo() { 44*795d594fSAndroid Build Coastguard Worker System.out.println("foo_A"); 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker public static final Lookup lookup = MethodHandles.lookup(); 48*795d594fSAndroid Build Coastguard Worker } 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker public static class B extends A { foo()51*795d594fSAndroid Build Coastguard Worker public void foo() { 52*795d594fSAndroid Build Coastguard Worker System.out.println("foo_B"); 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker public static final Lookup lookup = MethodHandles.lookup(); 56*795d594fSAndroid Build Coastguard Worker } 57*795d594fSAndroid Build Coastguard Worker 58*795d594fSAndroid Build Coastguard Worker public static class C extends B { 59*795d594fSAndroid Build Coastguard Worker public static final Lookup lookup = MethodHandles.lookup(); 60*795d594fSAndroid Build Coastguard Worker } 61*795d594fSAndroid Build Coastguard Worker 62*795d594fSAndroid Build Coastguard Worker public static class D { privateRyan()63*795d594fSAndroid Build Coastguard Worker private final void privateRyan() { 64*795d594fSAndroid Build Coastguard Worker System.out.println("privateRyan_D"); 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker public static final Lookup lookup = MethodHandles.lookup(); 68*795d594fSAndroid Build Coastguard Worker } 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker public static class E extends D { 71*795d594fSAndroid Build Coastguard Worker public static final Lookup lookup = MethodHandles.lookup(); 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker private interface F { sayHi()75*795d594fSAndroid Build Coastguard Worker public default void sayHi() { 76*795d594fSAndroid Build Coastguard Worker System.out.println("F.sayHi()"); 77*795d594fSAndroid Build Coastguard Worker } 78*795d594fSAndroid Build Coastguard Worker } 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker public static class G implements F { sayHi()81*795d594fSAndroid Build Coastguard Worker public void sayHi() { 82*795d594fSAndroid Build Coastguard Worker System.out.println("G.sayHi()"); 83*795d594fSAndroid Build Coastguard Worker } getLookup()84*795d594fSAndroid Build Coastguard Worker public MethodHandles.Lookup getLookup() { 85*795d594fSAndroid Build Coastguard Worker return MethodHandles.lookup(); 86*795d594fSAndroid Build Coastguard Worker } 87*795d594fSAndroid Build Coastguard Worker } 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker public static class H implements Chatty { chatter()90*795d594fSAndroid Build Coastguard Worker public void chatter() { 91*795d594fSAndroid Build Coastguard Worker System.out.println("H.chatter()"); 92*795d594fSAndroid Build Coastguard Worker } getLookup()93*795d594fSAndroid Build Coastguard Worker public MethodHandles.Lookup getLookup() { 94*795d594fSAndroid Build Coastguard Worker return MethodHandles.lookup(); 95*795d594fSAndroid Build Coastguard Worker } 96*795d594fSAndroid Build Coastguard Worker } 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker public static class I { someVoidMethod()99*795d594fSAndroid Build Coastguard Worker public static void someVoidMethod() { 100*795d594fSAndroid Build Coastguard Worker } 101*795d594fSAndroid Build Coastguard Worker } 102*795d594fSAndroid Build Coastguard Worker main(String[] args)103*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws Throwable { 104*795d594fSAndroid Build Coastguard Worker testfindSpecial_invokeSuperBehaviour(); 105*795d594fSAndroid Build Coastguard Worker testfindSpecial_invokeDirectBehaviour(); 106*795d594fSAndroid Build Coastguard Worker testExceptionDetailMessages(); 107*795d594fSAndroid Build Coastguard Worker testfindVirtual(); 108*795d594fSAndroid Build Coastguard Worker testfindStatic(); 109*795d594fSAndroid Build Coastguard Worker testUnreflects(); 110*795d594fSAndroid Build Coastguard Worker testAsType(); 111*795d594fSAndroid Build Coastguard Worker testConstructors(); 112*795d594fSAndroid Build Coastguard Worker testStringConstructors(); 113*795d594fSAndroid Build Coastguard Worker testReturnValues(); 114*795d594fSAndroid Build Coastguard Worker testReturnValueConversions(); 115*795d594fSAndroid Build Coastguard Worker testVariableArity(); 116*795d594fSAndroid Build Coastguard Worker testVariableArity_MethodHandles_bind(); 117*795d594fSAndroid Build Coastguard Worker testRevealDirect(); 118*795d594fSAndroid Build Coastguard Worker testReflectiveCalls(); 119*795d594fSAndroid Build Coastguard Worker testInterfaceSpecial(); 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker testfindSpecial_invokeSuperBehaviour()122*795d594fSAndroid Build Coastguard Worker public static void testfindSpecial_invokeSuperBehaviour() throws Throwable { 123*795d594fSAndroid Build Coastguard Worker // This is equivalent to an invoke-super instruction where the referrer 124*795d594fSAndroid Build Coastguard Worker // is B.class. 125*795d594fSAndroid Build Coastguard Worker MethodHandle mh1 = B.lookup.findSpecial(A.class /* refC */, "foo", 126*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class), B.class /* specialCaller */); 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker A aInstance = new A(); 129*795d594fSAndroid Build Coastguard Worker B bInstance = new B(); 130*795d594fSAndroid Build Coastguard Worker C cInstance = new C(); 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker // This should be as if an invoke-super was called from one of B's methods. 133*795d594fSAndroid Build Coastguard Worker mh1.invokeExact(bInstance); 134*795d594fSAndroid Build Coastguard Worker mh1.invoke(bInstance); 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker // This should not work. The receiver type in the handle will be suitably 137*795d594fSAndroid Build Coastguard Worker // restricted to B and subclasses. 138*795d594fSAndroid Build Coastguard Worker try { 139*795d594fSAndroid Build Coastguard Worker mh1.invoke(aInstance); 140*795d594fSAndroid Build Coastguard Worker System.out.println("mh1.invoke(aInstance) should not succeeed"); 141*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException expected) { 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Worker try { 145*795d594fSAndroid Build Coastguard Worker mh1.invokeExact(aInstance); 146*795d594fSAndroid Build Coastguard Worker System.out.println("mh1.invoke(aInstance) should not succeeed"); 147*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException expected) { 148*795d594fSAndroid Build Coastguard Worker } 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // This should *still* be as if an invoke-super was called from one of C's 151*795d594fSAndroid Build Coastguard Worker // methods, despite the fact that we're operating on a C. 152*795d594fSAndroid Build Coastguard Worker mh1.invoke(cInstance); 153*795d594fSAndroid Build Coastguard Worker 154*795d594fSAndroid Build Coastguard Worker // Now that C is the special caller, the next invoke will call B.foo. 155*795d594fSAndroid Build Coastguard Worker MethodHandle mh2 = C.lookup.findSpecial(A.class /* refC */, "foo", 156*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class), C.class /* specialCaller */); 157*795d594fSAndroid Build Coastguard Worker mh2.invokeExact(cInstance); 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker // Shouldn't allow invoke-super semantics from an unrelated special caller. 160*795d594fSAndroid Build Coastguard Worker try { 161*795d594fSAndroid Build Coastguard Worker C.lookup.findSpecial(A.class, "foo", 162*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class), D.class /* specialCaller */); 163*795d594fSAndroid Build Coastguard Worker System.out.println("findSpecial(A.class, foo, .. D.class) unexpectedly succeeded."); 164*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker // Check return type matches for find. 168*795d594fSAndroid Build Coastguard Worker try { 169*795d594fSAndroid Build Coastguard Worker B.lookup.findSpecial(A.class /* refC */, "foo", 170*795d594fSAndroid Build Coastguard Worker MethodType.methodType(int.class), B.class /* specialCaller */); 171*795d594fSAndroid Build Coastguard Worker fail(); 172*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 173*795d594fSAndroid Build Coastguard Worker // Check constructors 174*795d594fSAndroid Build Coastguard Worker try { 175*795d594fSAndroid Build Coastguard Worker B.lookup.findSpecial(A.class /* refC */, "<init>", 176*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class), B.class /* specialCaller */); 177*795d594fSAndroid Build Coastguard Worker fail(); 178*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 179*795d594fSAndroid Build Coastguard Worker } 180*795d594fSAndroid Build Coastguard Worker testfindSpecial_invokeDirectBehaviour()181*795d594fSAndroid Build Coastguard Worker public static void testfindSpecial_invokeDirectBehaviour() throws Throwable { 182*795d594fSAndroid Build Coastguard Worker D dInstance = new D(); 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker MethodHandle mh3 = D.lookup.findSpecial(D.class, "privateRyan", 185*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class), D.class /* specialCaller */); 186*795d594fSAndroid Build Coastguard Worker mh3.invoke(dInstance); 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker try { 189*795d594fSAndroid Build Coastguard Worker mh3.invokeExact((D) null); 190*795d594fSAndroid Build Coastguard Worker fail("Expected NPE to be thrown"); 191*795d594fSAndroid Build Coastguard Worker } catch (NullPointerException expected) { 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker // The private method shouldn't be accessible from any special caller except 195*795d594fSAndroid Build Coastguard Worker // itself... 196*795d594fSAndroid Build Coastguard Worker try { 197*795d594fSAndroid Build Coastguard Worker D.lookup.findSpecial(D.class, "privateRyan", MethodType.methodType(void.class), C.class); 198*795d594fSAndroid Build Coastguard Worker System.out.println("findSpecial(privateRyan, C.class) unexpectedly succeeded"); 199*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 200*795d594fSAndroid Build Coastguard Worker } 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker // ... or from any lookup context except its own. 203*795d594fSAndroid Build Coastguard Worker try { 204*795d594fSAndroid Build Coastguard Worker E.lookup.findSpecial(D.class, "privateRyan", MethodType.methodType(void.class), E.class); 205*795d594fSAndroid Build Coastguard Worker System.out.println("findSpecial(privateRyan, E.class) unexpectedly succeeded"); 206*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 207*795d594fSAndroid Build Coastguard Worker } 208*795d594fSAndroid Build Coastguard Worker } 209*795d594fSAndroid Build Coastguard Worker testExceptionDetailMessages()210*795d594fSAndroid Build Coastguard Worker public static void testExceptionDetailMessages() throws Throwable { 211*795d594fSAndroid Build Coastguard Worker MethodHandle handle = MethodHandles.lookup().findVirtual(String.class, "concat", 212*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, String.class)); 213*795d594fSAndroid Build Coastguard Worker 214*795d594fSAndroid Build Coastguard Worker try { 215*795d594fSAndroid Build Coastguard Worker handle.invokeExact("a", new Object()); 216*795d594fSAndroid Build Coastguard Worker System.out.println("invokeExact(\"a\", new Object()) unexpectedly succeeded."); 217*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException ex) { 218*795d594fSAndroid Build Coastguard Worker System.out.println("Received WrongMethodTypeException exception"); 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker public interface Foo { foo()223*795d594fSAndroid Build Coastguard Worker public String foo(); 224*795d594fSAndroid Build Coastguard Worker } 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker public interface Bar extends Foo { bar()227*795d594fSAndroid Build Coastguard Worker public String bar(); 228*795d594fSAndroid Build Coastguard Worker } 229*795d594fSAndroid Build Coastguard Worker 230*795d594fSAndroid Build Coastguard Worker public static abstract class BarAbstractSuper { abstractSuperPublicMethod()231*795d594fSAndroid Build Coastguard Worker public abstract String abstractSuperPublicMethod(); 232*795d594fSAndroid Build Coastguard Worker } 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker public static class BarSuper extends BarAbstractSuper { superPublicMethod()235*795d594fSAndroid Build Coastguard Worker public String superPublicMethod() { 236*795d594fSAndroid Build Coastguard Worker return "superPublicMethod"; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker superProtectedMethod()239*795d594fSAndroid Build Coastguard Worker protected String superProtectedMethod() { 240*795d594fSAndroid Build Coastguard Worker return "superProtectedMethod"; 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker abstractSuperPublicMethod()243*795d594fSAndroid Build Coastguard Worker public String abstractSuperPublicMethod() { 244*795d594fSAndroid Build Coastguard Worker return "abstractSuperPublicMethod"; 245*795d594fSAndroid Build Coastguard Worker } 246*795d594fSAndroid Build Coastguard Worker superPackageMethod()247*795d594fSAndroid Build Coastguard Worker String superPackageMethod() { 248*795d594fSAndroid Build Coastguard Worker return "superPackageMethod"; 249*795d594fSAndroid Build Coastguard Worker } 250*795d594fSAndroid Build Coastguard Worker } 251*795d594fSAndroid Build Coastguard Worker 252*795d594fSAndroid Build Coastguard Worker public static class BarImpl extends BarSuper implements Bar { BarImpl()253*795d594fSAndroid Build Coastguard Worker public BarImpl() { 254*795d594fSAndroid Build Coastguard Worker } 255*795d594fSAndroid Build Coastguard Worker 256*795d594fSAndroid Build Coastguard Worker @Override foo()257*795d594fSAndroid Build Coastguard Worker public String foo() { 258*795d594fSAndroid Build Coastguard Worker return "foo"; 259*795d594fSAndroid Build Coastguard Worker } 260*795d594fSAndroid Build Coastguard Worker 261*795d594fSAndroid Build Coastguard Worker @Override bar()262*795d594fSAndroid Build Coastguard Worker public String bar() { 263*795d594fSAndroid Build Coastguard Worker return "bar"; 264*795d594fSAndroid Build Coastguard Worker } 265*795d594fSAndroid Build Coastguard Worker add(int x, int y)266*795d594fSAndroid Build Coastguard Worker public String add(int x, int y) { 267*795d594fSAndroid Build Coastguard Worker return Arrays.toString(new int[] { x, y }); 268*795d594fSAndroid Build Coastguard Worker } 269*795d594fSAndroid Build Coastguard Worker privateMethod()270*795d594fSAndroid Build Coastguard Worker private String privateMethod() { return "privateMethod"; } 271*795d594fSAndroid Build Coastguard Worker staticMethod()272*795d594fSAndroid Build Coastguard Worker public static String staticMethod() { return staticString; } 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker private static String staticString; 275*795d594fSAndroid Build Coastguard Worker 276*795d594fSAndroid Build Coastguard Worker { 277*795d594fSAndroid Build Coastguard Worker // Static constructor 278*795d594fSAndroid Build Coastguard Worker staticString = Long.toString(System.currentTimeMillis()); 279*795d594fSAndroid Build Coastguard Worker } 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker static final MethodHandles.Lookup lookup = MethodHandles.lookup(); 282*795d594fSAndroid Build Coastguard Worker } 283*795d594fSAndroid Build Coastguard Worker testfindVirtual()284*795d594fSAndroid Build Coastguard Worker public static void testfindVirtual() throws Throwable { 285*795d594fSAndroid Build Coastguard Worker // Virtual lookups on static methods should not succeed. 286*795d594fSAndroid Build Coastguard Worker try { 287*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findVirtual( 288*795d594fSAndroid Build Coastguard Worker BarImpl.class, "staticMethod", MethodType.methodType(String.class)); 289*795d594fSAndroid Build Coastguard Worker System.out.println("findVirtual(staticMethod) unexpectedly succeeded"); 290*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 291*795d594fSAndroid Build Coastguard Worker } 292*795d594fSAndroid Build Coastguard Worker 293*795d594fSAndroid Build Coastguard Worker // Virtual lookups on private methods should not succeed, unless the Lookup 294*795d594fSAndroid Build Coastguard Worker // context had sufficient privileges. 295*795d594fSAndroid Build Coastguard Worker try { 296*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findVirtual( 297*795d594fSAndroid Build Coastguard Worker BarImpl.class, "privateMethod", MethodType.methodType(String.class)); 298*795d594fSAndroid Build Coastguard Worker System.out.println("findVirtual(privateMethod) unexpectedly succeeded"); 299*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 300*795d594fSAndroid Build Coastguard Worker } 301*795d594fSAndroid Build Coastguard Worker 302*795d594fSAndroid Build Coastguard Worker // Virtual lookup on a private method with a context that *does* have sufficient 303*795d594fSAndroid Build Coastguard Worker // privileges. 304*795d594fSAndroid Build Coastguard Worker MethodHandle mh = BarImpl.lookup.findVirtual( 305*795d594fSAndroid Build Coastguard Worker BarImpl.class, "privateMethod", MethodType.methodType(String.class)); 306*795d594fSAndroid Build Coastguard Worker String str = (String) mh.invoke(new BarImpl()); 307*795d594fSAndroid Build Coastguard Worker if (!"privateMethod".equals(str)) { 308*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#privateMethod: " + str); 309*795d594fSAndroid Build Coastguard Worker } 310*795d594fSAndroid Build Coastguard Worker 311*795d594fSAndroid Build Coastguard Worker // Find virtual must find interface methods defined by interfaces implemented 312*795d594fSAndroid Build Coastguard Worker // by the class. 313*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "foo", 314*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 315*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 316*795d594fSAndroid Build Coastguard Worker if (!"foo".equals(str)) { 317*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#foo: " + str); 318*795d594fSAndroid Build Coastguard Worker } 319*795d594fSAndroid Build Coastguard Worker 320*795d594fSAndroid Build Coastguard Worker // Find virtual should check rtype. 321*795d594fSAndroid Build Coastguard Worker try { 322*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "foo", 323*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 324*795d594fSAndroid Build Coastguard Worker fail(); 325*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 326*795d594fSAndroid Build Coastguard Worker 327*795d594fSAndroid Build Coastguard Worker // And ptypes 328*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual( 329*795d594fSAndroid Build Coastguard Worker BarImpl.class, "add", MethodType.methodType(String.class, int.class, int.class)); 330*795d594fSAndroid Build Coastguard Worker try { 331*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual( 332*795d594fSAndroid Build Coastguard Worker BarImpl.class, "add", MethodType.methodType(String.class, Integer.class, int.class)); 333*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker // .. and their super-interfaces. 336*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "bar", 337*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 338*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 339*795d594fSAndroid Build Coastguard Worker if (!"bar".equals(str)) { 340*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#bar: " + str); 341*795d594fSAndroid Build Coastguard Worker } 342*795d594fSAndroid Build Coastguard Worker 343*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(Bar.class, "bar", 344*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 345*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 346*795d594fSAndroid Build Coastguard Worker if (!"bar".equals(str)) { 347*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#bar: " + str); 348*795d594fSAndroid Build Coastguard Worker } 349*795d594fSAndroid Build Coastguard Worker 350*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarAbstractSuper.class, "abstractSuperPublicMethod", 351*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 352*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 353*795d594fSAndroid Build Coastguard Worker if (!"abstractSuperPublicMethod".equals(str)) { 354*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#abstractSuperPublicMethod: " + str); 355*795d594fSAndroid Build Coastguard Worker } 356*795d594fSAndroid Build Coastguard Worker 357*795d594fSAndroid Build Coastguard Worker // We should also be able to lookup public / protected / package methods in 358*795d594fSAndroid Build Coastguard Worker // the super class, given sufficient access privileges. 359*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "superPublicMethod", 360*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 361*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 362*795d594fSAndroid Build Coastguard Worker if (!"superPublicMethod".equals(str)) { 363*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#superPublicMethod: " + str); 364*795d594fSAndroid Build Coastguard Worker } 365*795d594fSAndroid Build Coastguard Worker 366*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "superProtectedMethod", 367*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 368*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 369*795d594fSAndroid Build Coastguard Worker if (!"superProtectedMethod".equals(str)) { 370*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#superProtectedMethod: " + str); 371*795d594fSAndroid Build Coastguard Worker } 372*795d594fSAndroid Build Coastguard Worker 373*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(BarImpl.class, "superPackageMethod", 374*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 375*795d594fSAndroid Build Coastguard Worker str = (String) mh.invoke(new BarImpl()); 376*795d594fSAndroid Build Coastguard Worker if (!"superPackageMethod".equals(str)) { 377*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpected return value for BarImpl#superPackageMethod: " + str); 378*795d594fSAndroid Build Coastguard Worker } 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker try { 381*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findVirtual(BarImpl.class, "<init>", 382*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 383*795d594fSAndroid Build Coastguard Worker fail(); 384*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 385*795d594fSAndroid Build Coastguard Worker } 386*795d594fSAndroid Build Coastguard Worker testfindStatic()387*795d594fSAndroid Build Coastguard Worker public static void testfindStatic() throws Throwable { 388*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic(BarImpl.class, "staticMethod", 389*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 390*795d594fSAndroid Build Coastguard Worker try { 391*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic(BarImpl.class, "staticMethod", 392*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 393*795d594fSAndroid Build Coastguard Worker fail(); 394*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 395*795d594fSAndroid Build Coastguard Worker try { 396*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic(BarImpl.class, "staticMethod", 397*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, int.class)); 398*795d594fSAndroid Build Coastguard Worker fail(); 399*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 400*795d594fSAndroid Build Coastguard Worker try { 401*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic(BarImpl.class, "<clinit>", 402*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 403*795d594fSAndroid Build Coastguard Worker fail(); 404*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 405*795d594fSAndroid Build Coastguard Worker try { 406*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic(BarImpl.class, "<init>", 407*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 408*795d594fSAndroid Build Coastguard Worker fail(); 409*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 410*795d594fSAndroid Build Coastguard Worker } 411*795d594fSAndroid Build Coastguard Worker 412*795d594fSAndroid Build Coastguard Worker static class UnreflectTester { 413*795d594fSAndroid Build Coastguard Worker public String publicField; 414*795d594fSAndroid Build Coastguard Worker private String privateField; 415*795d594fSAndroid Build Coastguard Worker 416*795d594fSAndroid Build Coastguard Worker public static String publicStaticField = "publicStaticValue"; 417*795d594fSAndroid Build Coastguard Worker private static String privateStaticField = "privateStaticValue"; 418*795d594fSAndroid Build Coastguard Worker UnreflectTester(String val)419*795d594fSAndroid Build Coastguard Worker private UnreflectTester(String val) { 420*795d594fSAndroid Build Coastguard Worker publicField = val; 421*795d594fSAndroid Build Coastguard Worker privateField = val; 422*795d594fSAndroid Build Coastguard Worker } 423*795d594fSAndroid Build Coastguard Worker 424*795d594fSAndroid Build Coastguard Worker // NOTE: The boolean constructor argument only exists to give this a 425*795d594fSAndroid Build Coastguard Worker // different signature. UnreflectTester(String val, boolean unused)426*795d594fSAndroid Build Coastguard Worker public UnreflectTester(String val, boolean unused) { 427*795d594fSAndroid Build Coastguard Worker this(val); 428*795d594fSAndroid Build Coastguard Worker } 429*795d594fSAndroid Build Coastguard Worker privateStaticMethod()430*795d594fSAndroid Build Coastguard Worker private static String privateStaticMethod() { 431*795d594fSAndroid Build Coastguard Worker return "privateStaticMethod"; 432*795d594fSAndroid Build Coastguard Worker } 433*795d594fSAndroid Build Coastguard Worker privateMethod()434*795d594fSAndroid Build Coastguard Worker private String privateMethod() { 435*795d594fSAndroid Build Coastguard Worker return "privateMethod"; 436*795d594fSAndroid Build Coastguard Worker } 437*795d594fSAndroid Build Coastguard Worker publicStaticMethod()438*795d594fSAndroid Build Coastguard Worker public static String publicStaticMethod() { 439*795d594fSAndroid Build Coastguard Worker return "publicStaticMethod"; 440*795d594fSAndroid Build Coastguard Worker } 441*795d594fSAndroid Build Coastguard Worker publicMethod()442*795d594fSAndroid Build Coastguard Worker public String publicMethod() { 443*795d594fSAndroid Build Coastguard Worker return "publicMethod"; 444*795d594fSAndroid Build Coastguard Worker } 445*795d594fSAndroid Build Coastguard Worker publicVarArgsMethod(String... args)446*795d594fSAndroid Build Coastguard Worker public String publicVarArgsMethod(String... args) { 447*795d594fSAndroid Build Coastguard Worker return "publicVarArgsMethod"; 448*795d594fSAndroid Build Coastguard Worker } 449*795d594fSAndroid Build Coastguard Worker } 450*795d594fSAndroid Build Coastguard Worker testUnreflects()451*795d594fSAndroid Build Coastguard Worker public static void testUnreflects() throws Throwable { 452*795d594fSAndroid Build Coastguard Worker UnreflectTester instance = new UnreflectTester("unused"); 453*795d594fSAndroid Build Coastguard Worker Method publicMethod = UnreflectTester.class.getMethod("publicMethod"); 454*795d594fSAndroid Build Coastguard Worker 455*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().unreflect(publicMethod); 456*795d594fSAndroid Build Coastguard Worker assertEquals("publicMethod", (String) mh.invoke(instance)); 457*795d594fSAndroid Build Coastguard Worker assertEquals("publicMethod", (String) mh.invokeExact(instance)); 458*795d594fSAndroid Build Coastguard Worker 459*795d594fSAndroid Build Coastguard Worker Method publicStaticMethod = UnreflectTester.class.getMethod("publicStaticMethod"); 460*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflect(publicStaticMethod); 461*795d594fSAndroid Build Coastguard Worker assertEquals("publicStaticMethod", (String) mh.invoke()); 462*795d594fSAndroid Build Coastguard Worker assertEquals("publicStaticMethod", (String) mh.invokeExact()); 463*795d594fSAndroid Build Coastguard Worker 464*795d594fSAndroid Build Coastguard Worker Method privateMethod = UnreflectTester.class.getDeclaredMethod("privateMethod"); 465*795d594fSAndroid Build Coastguard Worker try { 466*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflect(privateMethod); 467*795d594fSAndroid Build Coastguard Worker fail(); 468*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) {} 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker privateMethod.setAccessible(true); 471*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflect(privateMethod); 472*795d594fSAndroid Build Coastguard Worker assertEquals("privateMethod", (String) mh.invoke(instance)); 473*795d594fSAndroid Build Coastguard Worker assertEquals("privateMethod", (String) mh.invokeExact(instance)); 474*795d594fSAndroid Build Coastguard Worker 475*795d594fSAndroid Build Coastguard Worker Method privateStaticMethod = UnreflectTester.class.getDeclaredMethod("privateStaticMethod"); 476*795d594fSAndroid Build Coastguard Worker try { 477*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflect(privateStaticMethod); 478*795d594fSAndroid Build Coastguard Worker fail(); 479*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) {} 480*795d594fSAndroid Build Coastguard Worker 481*795d594fSAndroid Build Coastguard Worker privateStaticMethod.setAccessible(true); 482*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflect(privateStaticMethod); 483*795d594fSAndroid Build Coastguard Worker assertEquals("privateStaticMethod", (String) mh.invoke()); 484*795d594fSAndroid Build Coastguard Worker assertEquals("privateStaticMethod", (String) mh.invokeExact()); 485*795d594fSAndroid Build Coastguard Worker 486*795d594fSAndroid Build Coastguard Worker Constructor privateConstructor = UnreflectTester.class.getDeclaredConstructor(String.class); 487*795d594fSAndroid Build Coastguard Worker try { 488*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectConstructor(privateConstructor); 489*795d594fSAndroid Build Coastguard Worker fail(); 490*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) {} 491*795d594fSAndroid Build Coastguard Worker 492*795d594fSAndroid Build Coastguard Worker privateConstructor.setAccessible(true); 493*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectConstructor(privateConstructor); 494*795d594fSAndroid Build Coastguard Worker instance = (UnreflectTester) mh.invokeExact("abc"); 495*795d594fSAndroid Build Coastguard Worker assertEquals("abc", instance.publicField); 496*795d594fSAndroid Build Coastguard Worker instance = (UnreflectTester) mh.invoke("def"); 497*795d594fSAndroid Build Coastguard Worker assertEquals("def", instance.publicField); 498*795d594fSAndroid Build Coastguard Worker Constructor publicConstructor = UnreflectTester.class.getConstructor(String.class, 499*795d594fSAndroid Build Coastguard Worker boolean.class); 500*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectConstructor(publicConstructor); 501*795d594fSAndroid Build Coastguard Worker instance = (UnreflectTester) mh.invokeExact("abc", false); 502*795d594fSAndroid Build Coastguard Worker assertEquals("abc", instance.publicField); 503*795d594fSAndroid Build Coastguard Worker instance = (UnreflectTester) mh.invoke("def", true); 504*795d594fSAndroid Build Coastguard Worker assertEquals("def", instance.publicField); 505*795d594fSAndroid Build Coastguard Worker 506*795d594fSAndroid Build Coastguard Worker // TODO(narayan): Non exact invokes for field sets/gets are not implemented yet. 507*795d594fSAndroid Build Coastguard Worker // 508*795d594fSAndroid Build Coastguard Worker // assertEquals("instanceValue", (String) mh.invoke(new UnreflectTester("instanceValue"))); 509*795d594fSAndroid Build Coastguard Worker Field publicField = UnreflectTester.class.getField("publicField"); 510*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(publicField); 511*795d594fSAndroid Build Coastguard Worker instance = new UnreflectTester("instanceValue"); 512*795d594fSAndroid Build Coastguard Worker assertEquals("instanceValue", (String) mh.invokeExact(instance)); 513*795d594fSAndroid Build Coastguard Worker 514*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(publicField); 515*795d594fSAndroid Build Coastguard Worker instance = new UnreflectTester("instanceValue"); 516*795d594fSAndroid Build Coastguard Worker mh.invokeExact(instance, "updatedInstanceValue"); 517*795d594fSAndroid Build Coastguard Worker assertEquals("updatedInstanceValue", instance.publicField); 518*795d594fSAndroid Build Coastguard Worker 519*795d594fSAndroid Build Coastguard Worker Field publicStaticField = UnreflectTester.class.getField("publicStaticField"); 520*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(publicStaticField); 521*795d594fSAndroid Build Coastguard Worker UnreflectTester.publicStaticField = "updatedStaticValue"; 522*795d594fSAndroid Build Coastguard Worker assertEquals("updatedStaticValue", (String) mh.invokeExact()); 523*795d594fSAndroid Build Coastguard Worker 524*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(publicStaticField); 525*795d594fSAndroid Build Coastguard Worker UnreflectTester.publicStaticField = "updatedStaticValue"; 526*795d594fSAndroid Build Coastguard Worker mh.invokeExact("updatedStaticValue2"); 527*795d594fSAndroid Build Coastguard Worker assertEquals("updatedStaticValue2", UnreflectTester.publicStaticField); 528*795d594fSAndroid Build Coastguard Worker 529*795d594fSAndroid Build Coastguard Worker Field privateField = UnreflectTester.class.getDeclaredField("privateField"); 530*795d594fSAndroid Build Coastguard Worker try { 531*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(privateField); 532*795d594fSAndroid Build Coastguard Worker fail(); 533*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 534*795d594fSAndroid Build Coastguard Worker } 535*795d594fSAndroid Build Coastguard Worker try { 536*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(privateField); 537*795d594fSAndroid Build Coastguard Worker fail(); 538*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 539*795d594fSAndroid Build Coastguard Worker } 540*795d594fSAndroid Build Coastguard Worker 541*795d594fSAndroid Build Coastguard Worker privateField.setAccessible(true); 542*795d594fSAndroid Build Coastguard Worker 543*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(privateField); 544*795d594fSAndroid Build Coastguard Worker instance = new UnreflectTester("instanceValue"); 545*795d594fSAndroid Build Coastguard Worker assertEquals("instanceValue", (String) mh.invokeExact(instance)); 546*795d594fSAndroid Build Coastguard Worker 547*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(privateField); 548*795d594fSAndroid Build Coastguard Worker instance = new UnreflectTester("instanceValue"); 549*795d594fSAndroid Build Coastguard Worker mh.invokeExact(instance, "updatedInstanceValue"); 550*795d594fSAndroid Build Coastguard Worker assertEquals("updatedInstanceValue", instance.privateField); 551*795d594fSAndroid Build Coastguard Worker 552*795d594fSAndroid Build Coastguard Worker Field privateStaticField = UnreflectTester.class.getDeclaredField("privateStaticField"); 553*795d594fSAndroid Build Coastguard Worker try { 554*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(privateStaticField); 555*795d594fSAndroid Build Coastguard Worker fail(); 556*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 557*795d594fSAndroid Build Coastguard Worker } 558*795d594fSAndroid Build Coastguard Worker try { 559*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(privateStaticField); 560*795d594fSAndroid Build Coastguard Worker fail(); 561*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException expected) { 562*795d594fSAndroid Build Coastguard Worker } 563*795d594fSAndroid Build Coastguard Worker 564*795d594fSAndroid Build Coastguard Worker privateStaticField.setAccessible(true); 565*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectGetter(privateStaticField); 566*795d594fSAndroid Build Coastguard Worker privateStaticField.set(null, "updatedStaticValue"); 567*795d594fSAndroid Build Coastguard Worker assertEquals("updatedStaticValue", (String) mh.invokeExact()); 568*795d594fSAndroid Build Coastguard Worker 569*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().unreflectSetter(privateStaticField); 570*795d594fSAndroid Build Coastguard Worker privateStaticField.set(null, "updatedStaticValue"); 571*795d594fSAndroid Build Coastguard Worker mh.invokeExact("updatedStaticValue2"); 572*795d594fSAndroid Build Coastguard Worker assertEquals("updatedStaticValue2", (String) privateStaticField.get(null)); 573*795d594fSAndroid Build Coastguard Worker 574*795d594fSAndroid Build Coastguard Worker // unreflectSpecial testing - F is an interface that G implements 575*795d594fSAndroid Build Coastguard Worker 576*795d594fSAndroid Build Coastguard Worker G g = new G(); 577*795d594fSAndroid Build Coastguard Worker g.sayHi(); // prints "G.sayHi()" 578*795d594fSAndroid Build Coastguard Worker 579*795d594fSAndroid Build Coastguard Worker MethodHandles.Lookup lookupInG = g.getLookup(); 580*795d594fSAndroid Build Coastguard Worker Method methodInG = G.class.getDeclaredMethod("sayHi"); 581*795d594fSAndroid Build Coastguard Worker lookupInG.unreflectSpecial(methodInG, G.class).invoke(g); // prints "G.sayHi()" 582*795d594fSAndroid Build Coastguard Worker 583*795d594fSAndroid Build Coastguard Worker Method methodInF = F.class.getDeclaredMethod("sayHi"); 584*795d594fSAndroid Build Coastguard Worker lookupInG.unreflect(methodInF).invoke(g); // prints "G.sayHi()" 585*795d594fSAndroid Build Coastguard Worker lookupInG.in(G.class).unreflectSpecial(methodInF, G.class).invoke(g); // prints "F.sayHi()" 586*795d594fSAndroid Build Coastguard Worker lookupInG.unreflectSpecial(methodInF, G.class).bindTo(g).invokeWithArguments(); 587*795d594fSAndroid Build Coastguard Worker 588*795d594fSAndroid Build Coastguard Worker // unreflectSpecial testing - other.Chatty is an interface that H implements 589*795d594fSAndroid Build Coastguard Worker 590*795d594fSAndroid Build Coastguard Worker H h = new H(); 591*795d594fSAndroid Build Coastguard Worker h.chatter(); 592*795d594fSAndroid Build Coastguard Worker 593*795d594fSAndroid Build Coastguard Worker MethodHandles.Lookup lookupInH = h.getLookup(); 594*795d594fSAndroid Build Coastguard Worker Method methodInH = H.class.getDeclaredMethod("chatter"); 595*795d594fSAndroid Build Coastguard Worker lookupInH.unreflectSpecial(methodInH, H.class).invoke(h); 596*795d594fSAndroid Build Coastguard Worker 597*795d594fSAndroid Build Coastguard Worker Method methodInChatty = Chatty.class.getDeclaredMethod("chatter"); 598*795d594fSAndroid Build Coastguard Worker lookupInH.unreflect(methodInChatty).invoke(h); 599*795d594fSAndroid Build Coastguard Worker lookupInH.in(H.class).unreflectSpecial(methodInChatty, H.class).invoke(h); 600*795d594fSAndroid Build Coastguard Worker lookupInH.unreflectSpecial(methodInChatty, H.class).bindTo(h).invokeWithArguments(); 601*795d594fSAndroid Build Coastguard Worker } 602*795d594fSAndroid Build Coastguard Worker 603*795d594fSAndroid Build Coastguard Worker // This method only exists to fool Jack's handling of types. See b/32536744. getSequence()604*795d594fSAndroid Build Coastguard Worker public static CharSequence getSequence() { 605*795d594fSAndroid Build Coastguard Worker return "foo"; 606*795d594fSAndroid Build Coastguard Worker } 607*795d594fSAndroid Build Coastguard Worker testAsType()608*795d594fSAndroid Build Coastguard Worker public static void testAsType() throws Throwable { 609*795d594fSAndroid Build Coastguard Worker // The type of this handle is (String, String)String. 610*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().findVirtual(String.class, 611*795d594fSAndroid Build Coastguard Worker "concat", MethodType.methodType(String.class, String.class)); 612*795d594fSAndroid Build Coastguard Worker 613*795d594fSAndroid Build Coastguard Worker // Change it to (CharSequence, String)Object. 614*795d594fSAndroid Build Coastguard Worker MethodHandle asType = mh.asType( 615*795d594fSAndroid Build Coastguard Worker MethodType.methodType(Object.class, CharSequence.class, String.class)); 616*795d594fSAndroid Build Coastguard Worker 617*795d594fSAndroid Build Coastguard Worker Object obj = asType.invokeExact((CharSequence) getSequence(), "bar"); 618*795d594fSAndroid Build Coastguard Worker assertEquals("foobar", (String) obj); 619*795d594fSAndroid Build Coastguard Worker 620*795d594fSAndroid Build Coastguard Worker // Should fail due to a wrong return type. 621*795d594fSAndroid Build Coastguard Worker try { 622*795d594fSAndroid Build Coastguard Worker String str = (String) asType.invokeExact((CharSequence) getSequence(), "bar"); 623*795d594fSAndroid Build Coastguard Worker fail(); 624*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException expected) { 625*795d594fSAndroid Build Coastguard Worker } 626*795d594fSAndroid Build Coastguard Worker 627*795d594fSAndroid Build Coastguard Worker // Should fail due to a wrong argument type (String instead of Charsequence). 628*795d594fSAndroid Build Coastguard Worker try { 629*795d594fSAndroid Build Coastguard Worker String str = (String) asType.invokeExact("baz", "bar"); 630*795d594fSAndroid Build Coastguard Worker fail(); 631*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException expected) { 632*795d594fSAndroid Build Coastguard Worker } 633*795d594fSAndroid Build Coastguard Worker 634*795d594fSAndroid Build Coastguard Worker // Calls to asType should fail if the types are not convertible. 635*795d594fSAndroid Build Coastguard Worker // 636*795d594fSAndroid Build Coastguard Worker // Bad return type conversion. 637*795d594fSAndroid Build Coastguard Worker try { 638*795d594fSAndroid Build Coastguard Worker mh.asType(MethodType.methodType(int.class, String.class, String.class)); 639*795d594fSAndroid Build Coastguard Worker fail(); 640*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException expected) { 641*795d594fSAndroid Build Coastguard Worker } 642*795d594fSAndroid Build Coastguard Worker 643*795d594fSAndroid Build Coastguard Worker // Bad argument conversion. 644*795d594fSAndroid Build Coastguard Worker try { 645*795d594fSAndroid Build Coastguard Worker mh.asType(MethodType.methodType(String.class, int.class, String.class)); 646*795d594fSAndroid Build Coastguard Worker fail(); 647*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException expected) { 648*795d594fSAndroid Build Coastguard Worker } 649*795d594fSAndroid Build Coastguard Worker 650*795d594fSAndroid Build Coastguard Worker // Zero / null introduction 651*795d594fSAndroid Build Coastguard Worker MethodHandle voidMH = MethodHandles.lookup().findStatic(I.class, "someVoidMethod", 652*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 653*795d594fSAndroid Build Coastguard Worker { 654*795d594fSAndroid Build Coastguard Worker MethodHandle booleanMH = voidMH.asType(MethodType.methodType(boolean.class)); 655*795d594fSAndroid Build Coastguard Worker assertEquals(boolean.class, booleanMH.type().returnType()); 656*795d594fSAndroid Build Coastguard Worker assertEquals(false, booleanMH.invoke()); 657*795d594fSAndroid Build Coastguard Worker } 658*795d594fSAndroid Build Coastguard Worker { 659*795d594fSAndroid Build Coastguard Worker MethodHandle intMH = voidMH.asType(MethodType.methodType(int.class)); 660*795d594fSAndroid Build Coastguard Worker assertEquals(int.class, intMH.type().returnType()); 661*795d594fSAndroid Build Coastguard Worker assertEquals(0, intMH.invoke()); 662*795d594fSAndroid Build Coastguard Worker } 663*795d594fSAndroid Build Coastguard Worker { 664*795d594fSAndroid Build Coastguard Worker MethodHandle longMH = voidMH.asType(MethodType.methodType(long.class)); 665*795d594fSAndroid Build Coastguard Worker assertEquals(long.class, longMH.type().returnType()); 666*795d594fSAndroid Build Coastguard Worker assertEquals(0L, longMH.invoke()); 667*795d594fSAndroid Build Coastguard Worker } 668*795d594fSAndroid Build Coastguard Worker { 669*795d594fSAndroid Build Coastguard Worker MethodHandle objMH = voidMH.asType(MethodType.methodType(Object.class)); 670*795d594fSAndroid Build Coastguard Worker assertEquals(Object.class, objMH.type().returnType()); 671*795d594fSAndroid Build Coastguard Worker assertEquals(null, objMH.invoke()); 672*795d594fSAndroid Build Coastguard Worker } 673*795d594fSAndroid Build Coastguard Worker 674*795d594fSAndroid Build Coastguard Worker // Applying asType() twice. 675*795d594fSAndroid Build Coastguard Worker { 676*795d594fSAndroid Build Coastguard Worker MethodHandle valueOfMH = MethodHandles.lookup().findStatic(Integer.class, "valueOf", 677*795d594fSAndroid Build Coastguard Worker MethodType.methodType(Integer.class, int.class)); 678*795d594fSAndroid Build Coastguard Worker MethodHandle atMH = valueOfMH.asType(MethodType.methodType(int.class, Object.class)); 679*795d594fSAndroid Build Coastguard Worker MethodHandle at2MH = atMH.asType(MethodType.methodType(Integer.class, int.class)); 680*795d594fSAndroid Build Coastguard Worker assertEquals(valueOfMH.type(), at2MH.type()); 681*795d594fSAndroid Build Coastguard Worker assertEquals(Integer.valueOf(2), (Integer) valueOfMH.invokeExact(2)); 682*795d594fSAndroid Build Coastguard Worker assertEquals(12345678, (int) atMH.invokeExact((Object) Integer.valueOf(12345678))); 683*795d594fSAndroid Build Coastguard Worker assertEquals(Integer.valueOf(987654321), (Integer) at2MH.invokeExact(987654321)); 684*795d594fSAndroid Build Coastguard Worker } 685*795d594fSAndroid Build Coastguard Worker { 686*795d594fSAndroid Build Coastguard Worker MethodHandle valueOfMH = MethodHandles.lookup().findStatic(Double.class, "valueOf", 687*795d594fSAndroid Build Coastguard Worker MethodType.methodType(Double.class, double.class)); 688*795d594fSAndroid Build Coastguard Worker MethodHandle atMH = valueOfMH.asType(MethodType.methodType(double.class, Object.class)); 689*795d594fSAndroid Build Coastguard Worker MethodHandle at2MH = atMH.asType(MethodType.methodType(Double.class, double.class)); 690*795d594fSAndroid Build Coastguard Worker assertEquals(valueOfMH.type(), at2MH.type()); 691*795d594fSAndroid Build Coastguard Worker assertEquals(Double.valueOf(1.125e3), (Double) valueOfMH.invokeExact(1.125e3)); 692*795d594fSAndroid Build Coastguard Worker assertEquals(2.5e-3, (double) atMH.invokeExact((Object) Double.valueOf(2.5e-3))); 693*795d594fSAndroid Build Coastguard Worker assertEquals(Double.valueOf(3.125e-2), (Double) at2MH.invokeExact(3.125e-2)); 694*795d594fSAndroid Build Coastguard Worker } 695*795d594fSAndroid Build Coastguard Worker } 696*795d594fSAndroid Build Coastguard Worker assertTrue(boolean value)697*795d594fSAndroid Build Coastguard Worker public static void assertTrue(boolean value) { 698*795d594fSAndroid Build Coastguard Worker if (!value) { 699*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertTrue value: " + value); 700*795d594fSAndroid Build Coastguard Worker } 701*795d594fSAndroid Build Coastguard Worker } 702*795d594fSAndroid Build Coastguard Worker assertFalse(boolean value)703*795d594fSAndroid Build Coastguard Worker public static void assertFalse(boolean value) { 704*795d594fSAndroid Build Coastguard Worker if (value) { 705*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertTrue value: " + value); 706*795d594fSAndroid Build Coastguard Worker } 707*795d594fSAndroid Build Coastguard Worker } 708*795d594fSAndroid Build Coastguard Worker assertEquals(int i1, int i2)709*795d594fSAndroid Build Coastguard Worker public static void assertEquals(int i1, int i2) { 710*795d594fSAndroid Build Coastguard Worker if (i1 == i2) { return; } 711*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertEquals i1: " + i1 + ", i2: " + i2); 712*795d594fSAndroid Build Coastguard Worker } 713*795d594fSAndroid Build Coastguard Worker assertEquals(long i1, long i2)714*795d594fSAndroid Build Coastguard Worker public static void assertEquals(long i1, long i2) { 715*795d594fSAndroid Build Coastguard Worker if (i1 == i2) { return; } 716*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertEquals l1: " + i1 + ", l2: " + i2); 717*795d594fSAndroid Build Coastguard Worker } 718*795d594fSAndroid Build Coastguard Worker assertEquals(Object o, Object p)719*795d594fSAndroid Build Coastguard Worker public static void assertEquals(Object o, Object p) { 720*795d594fSAndroid Build Coastguard Worker if (o == p) { return; } 721*795d594fSAndroid Build Coastguard Worker if (o != null && p != null && o.equals(p)) { return; } 722*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertEquals: o1: " + o + ", o2: " + p); 723*795d594fSAndroid Build Coastguard Worker } 724*795d594fSAndroid Build Coastguard Worker assertEquals(String s1, String s2)725*795d594fSAndroid Build Coastguard Worker public static void assertEquals(String s1, String s2) { 726*795d594fSAndroid Build Coastguard Worker if (s1 == s2) { 727*795d594fSAndroid Build Coastguard Worker return; 728*795d594fSAndroid Build Coastguard Worker } 729*795d594fSAndroid Build Coastguard Worker 730*795d594fSAndroid Build Coastguard Worker if (s1 != null && s2 != null && s1.equals(s2)) { 731*795d594fSAndroid Build Coastguard Worker return; 732*795d594fSAndroid Build Coastguard Worker } 733*795d594fSAndroid Build Coastguard Worker 734*795d594fSAndroid Build Coastguard Worker throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2); 735*795d594fSAndroid Build Coastguard Worker } 736*795d594fSAndroid Build Coastguard Worker fail()737*795d594fSAndroid Build Coastguard Worker public static void fail() { 738*795d594fSAndroid Build Coastguard Worker System.out.println("fail"); 739*795d594fSAndroid Build Coastguard Worker Thread.dumpStack(); 740*795d594fSAndroid Build Coastguard Worker } 741*795d594fSAndroid Build Coastguard Worker fail(String message)742*795d594fSAndroid Build Coastguard Worker public static void fail(String message) { 743*795d594fSAndroid Build Coastguard Worker System.out.println("fail: " + message); 744*795d594fSAndroid Build Coastguard Worker Thread.dumpStack(); 745*795d594fSAndroid Build Coastguard Worker } 746*795d594fSAndroid Build Coastguard Worker testConstructors()747*795d594fSAndroid Build Coastguard Worker public static void testConstructors() throws Throwable { 748*795d594fSAndroid Build Coastguard Worker MethodHandle mh = 749*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findConstructor(Float.class, 750*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, 751*795d594fSAndroid Build Coastguard Worker float.class)); 752*795d594fSAndroid Build Coastguard Worker Float value = (Float) mh.invokeExact(0.33f); 753*795d594fSAndroid Build Coastguard Worker if (value.floatValue() != 0.33f) { 754*795d594fSAndroid Build Coastguard Worker fail("Unexpected float value from invokeExact " + value.floatValue()); 755*795d594fSAndroid Build Coastguard Worker } 756*795d594fSAndroid Build Coastguard Worker 757*795d594fSAndroid Build Coastguard Worker value = (Float) mh.invoke(3.34f); 758*795d594fSAndroid Build Coastguard Worker if (value.floatValue() != 3.34f) { 759*795d594fSAndroid Build Coastguard Worker fail("Unexpected float value from invoke " + value.floatValue()); 760*795d594fSAndroid Build Coastguard Worker } 761*795d594fSAndroid Build Coastguard Worker 762*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor(Double.class, 763*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, String.class)); 764*795d594fSAndroid Build Coastguard Worker Double d = (Double) mh.invoke("8.45e3"); 765*795d594fSAndroid Build Coastguard Worker if (d.doubleValue() != 8.45e3) { 766*795d594fSAndroid Build Coastguard Worker fail("Unexpected double value from Double(String) " + value.doubleValue()); 767*795d594fSAndroid Build Coastguard Worker } 768*795d594fSAndroid Build Coastguard Worker 769*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor(Double.class, 770*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, double.class)); 771*795d594fSAndroid Build Coastguard Worker d = (Double) mh.invoke(8.45e3); 772*795d594fSAndroid Build Coastguard Worker if (d.doubleValue() != 8.45e3) { 773*795d594fSAndroid Build Coastguard Worker fail("Unexpected double value from Double(double) " + value.doubleValue()); 774*795d594fSAndroid Build Coastguard Worker } 775*795d594fSAndroid Build Coastguard Worker 776*795d594fSAndroid Build Coastguard Worker // Primitive type 777*795d594fSAndroid Build Coastguard Worker try { 778*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor(int.class, MethodType.methodType(void.class)); 779*795d594fSAndroid Build Coastguard Worker fail("Unexpected lookup success for primitive constructor"); 780*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 781*795d594fSAndroid Build Coastguard Worker 782*795d594fSAndroid Build Coastguard Worker // Interface 783*795d594fSAndroid Build Coastguard Worker try { 784*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor(Readable.class, 785*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class)); 786*795d594fSAndroid Build Coastguard Worker fail("Unexpected lookup success for interface constructor"); 787*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 788*795d594fSAndroid Build Coastguard Worker 789*795d594fSAndroid Build Coastguard Worker // Abstract 790*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor(Process.class, MethodType.methodType(void.class)); 791*795d594fSAndroid Build Coastguard Worker try { 792*795d594fSAndroid Build Coastguard Worker mh.invoke(); 793*795d594fSAndroid Build Coastguard Worker fail("Unexpected ability to instantiate an abstract class"); 794*795d594fSAndroid Build Coastguard Worker } catch (InstantiationException e) {} 795*795d594fSAndroid Build Coastguard Worker 796*795d594fSAndroid Build Coastguard Worker // Non-existent 797*795d594fSAndroid Build Coastguard Worker try { 798*795d594fSAndroid Build Coastguard Worker MethodHandle bad = MethodHandles.lookup().findConstructor( 799*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(String.class, Float.class)); 800*795d594fSAndroid Build Coastguard Worker fail("Unexpected success for non-existent constructor"); 801*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 802*795d594fSAndroid Build Coastguard Worker 803*795d594fSAndroid Build Coastguard Worker // Non-void constructor search. (I)I instead of (I)V. 804*795d594fSAndroid Build Coastguard Worker try { 805*795d594fSAndroid Build Coastguard Worker MethodHandle foo = MethodHandles.lookup().findConstructor( 806*795d594fSAndroid Build Coastguard Worker Integer.class, MethodType.methodType(Integer.class, Integer.class)); 807*795d594fSAndroid Build Coastguard Worker fail("Unexpected success for non-void type for findConstructor"); 808*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 809*795d594fSAndroid Build Coastguard Worker 810*795d594fSAndroid Build Coastguard Worker // Array class constructor. 811*795d594fSAndroid Build Coastguard Worker try { 812*795d594fSAndroid Build Coastguard Worker MethodHandle foo = MethodHandles.lookup().findConstructor( 813*795d594fSAndroid Build Coastguard Worker Object[].class, MethodType.methodType(void.class)); 814*795d594fSAndroid Build Coastguard Worker fail("Unexpected success for array class type for findConstructor"); 815*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException e) {} 816*795d594fSAndroid Build Coastguard Worker 817*795d594fSAndroid Build Coastguard Worker // Child class constructor (b/143343351) 818*795d594fSAndroid Build Coastguard Worker { 819*795d594fSAndroid Build Coastguard Worker MethodHandle handle = MethodHandles.lookup().findConstructor( 820*795d594fSAndroid Build Coastguard Worker ArrayList.class, MethodType.methodType(void.class)); 821*795d594fSAndroid Build Coastguard Worker AbstractList list = (AbstractList) handle.asType(MethodType.methodType(AbstractList.class)) 822*795d594fSAndroid Build Coastguard Worker .invokeExact(); 823*795d594fSAndroid Build Coastguard Worker } 824*795d594fSAndroid Build Coastguard Worker } 825*795d594fSAndroid Build Coastguard Worker testStringConstructors()826*795d594fSAndroid Build Coastguard Worker public static void testStringConstructors() throws Throwable { 827*795d594fSAndroid Build Coastguard Worker final String testPattern = "The system as we know it is broken"; 828*795d594fSAndroid Build Coastguard Worker 829*795d594fSAndroid Build Coastguard Worker // String() 830*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().findConstructor( 831*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class)); 832*795d594fSAndroid Build Coastguard Worker String s = (String) mh.invokeExact(); 833*795d594fSAndroid Build Coastguard Worker if (!s.equals("")) { 834*795d594fSAndroid Build Coastguard Worker fail("Unexpected empty string constructor result: '" + s + "'"); 835*795d594fSAndroid Build Coastguard Worker } 836*795d594fSAndroid Build Coastguard Worker 837*795d594fSAndroid Build Coastguard Worker // String(String) 838*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 839*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, String.class)); 840*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(testPattern); 841*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 842*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 843*795d594fSAndroid Build Coastguard Worker } 844*795d594fSAndroid Build Coastguard Worker 845*795d594fSAndroid Build Coastguard Worker // String(char[]) 846*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 847*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, char[].class)); 848*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(testPattern.toCharArray()); 849*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 850*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 851*795d594fSAndroid Build Coastguard Worker } 852*795d594fSAndroid Build Coastguard Worker 853*795d594fSAndroid Build Coastguard Worker // String(char[], int, int) 854*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 855*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, char[].class, int.class, int.class)); 856*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(new char [] { 'a', 'b', 'c', 'd', 'e'}, 2, 3); 857*795d594fSAndroid Build Coastguard Worker if (!s.equals("cde")) { 858*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 859*795d594fSAndroid Build Coastguard Worker } 860*795d594fSAndroid Build Coastguard Worker 861*795d594fSAndroid Build Coastguard Worker // String(int[] codePoints, int offset, int count) 862*795d594fSAndroid Build Coastguard Worker StringBuffer sb = new StringBuffer(testPattern); 863*795d594fSAndroid Build Coastguard Worker int[] codePoints = new int[sb.codePointCount(0, sb.length())]; 864*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < sb.length(); ++i) { 865*795d594fSAndroid Build Coastguard Worker codePoints[i] = sb.codePointAt(i); 866*795d594fSAndroid Build Coastguard Worker } 867*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 868*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, int[].class, int.class, int.class)); 869*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(codePoints, 0, codePoints.length); 870*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 871*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 872*795d594fSAndroid Build Coastguard Worker } 873*795d594fSAndroid Build Coastguard Worker 874*795d594fSAndroid Build Coastguard Worker // String(byte ascii[], int hibyte, int offset, int count) 875*795d594fSAndroid Build Coastguard Worker byte [] ascii = testPattern.getBytes(StandardCharsets.US_ASCII); 876*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 877*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, byte[].class, int.class, int.class)); 878*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, 0, ascii.length); 879*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 880*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 881*795d594fSAndroid Build Coastguard Worker } 882*795d594fSAndroid Build Coastguard Worker 883*795d594fSAndroid Build Coastguard Worker // String(byte bytes[], int offset, int length, String charsetName) 884*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 885*795d594fSAndroid Build Coastguard Worker String.class, 886*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, byte[].class, int.class, int.class, String.class)); 887*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, 0, 5, StandardCharsets.US_ASCII.name()); 888*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern.substring(0, 5))) { 889*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 890*795d594fSAndroid Build Coastguard Worker } 891*795d594fSAndroid Build Coastguard Worker 892*795d594fSAndroid Build Coastguard Worker // String(byte bytes[], int offset, int length, Charset charset) 893*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 894*795d594fSAndroid Build Coastguard Worker String.class, 895*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, byte[].class, int.class, int.class, Charset.class)); 896*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, 0, 5, StandardCharsets.US_ASCII); 897*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern.substring(0, 5))) { 898*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 899*795d594fSAndroid Build Coastguard Worker } 900*795d594fSAndroid Build Coastguard Worker 901*795d594fSAndroid Build Coastguard Worker // String(byte bytes[], String charsetName) 902*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 903*795d594fSAndroid Build Coastguard Worker String.class, 904*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, byte[].class, String.class)); 905*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, StandardCharsets.US_ASCII.name()); 906*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 907*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 908*795d594fSAndroid Build Coastguard Worker } 909*795d594fSAndroid Build Coastguard Worker 910*795d594fSAndroid Build Coastguard Worker // String(byte bytes[], Charset charset) 911*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 912*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, byte[].class, Charset.class)); 913*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, StandardCharsets.US_ASCII); 914*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 915*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 916*795d594fSAndroid Build Coastguard Worker } 917*795d594fSAndroid Build Coastguard Worker 918*795d594fSAndroid Build Coastguard Worker // String(byte bytes[], int offset, int length) 919*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 920*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, byte[].class, int.class, int.class)); 921*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii, 1, ascii.length - 2); 922*795d594fSAndroid Build Coastguard Worker s = testPattern.charAt(0) + s + testPattern.charAt(testPattern.length() - 1); 923*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 924*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 925*795d594fSAndroid Build Coastguard Worker } 926*795d594fSAndroid Build Coastguard Worker 927*795d594fSAndroid Build Coastguard Worker // String(byte bytes[]) 928*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 929*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, byte[].class)); 930*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(ascii); 931*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 932*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 933*795d594fSAndroid Build Coastguard Worker } 934*795d594fSAndroid Build Coastguard Worker 935*795d594fSAndroid Build Coastguard Worker // String(StringBuffer buffer) 936*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 937*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class, StringBuffer.class)); 938*795d594fSAndroid Build Coastguard Worker s = (String) mh.invokeExact(sb); 939*795d594fSAndroid Build Coastguard Worker if (!s.equals(testPattern)) { 940*795d594fSAndroid Build Coastguard Worker fail("Unexpected string constructor result: '" + s + "'"); 941*795d594fSAndroid Build Coastguard Worker } 942*795d594fSAndroid Build Coastguard Worker 943*795d594fSAndroid Build Coastguard Worker // Child class constructor (b/143343351) 944*795d594fSAndroid Build Coastguard Worker { 945*795d594fSAndroid Build Coastguard Worker MethodHandle handle = MethodHandles.lookup().findConstructor( 946*795d594fSAndroid Build Coastguard Worker String.class, MethodType.methodType(void.class)); 947*795d594fSAndroid Build Coastguard Worker CharSequence o = (CharSequence) handle.asType(MethodType.methodType(CharSequence.class)) 948*795d594fSAndroid Build Coastguard Worker .invokeExact(); 949*795d594fSAndroid Build Coastguard Worker if (!o.equals("")) { 950*795d594fSAndroid Build Coastguard Worker fail("Unexpected child class constructor result: '" + o + "'"); 951*795d594fSAndroid Build Coastguard Worker } 952*795d594fSAndroid Build Coastguard Worker } 953*795d594fSAndroid Build Coastguard Worker System.out.println("String constructors done."); 954*795d594fSAndroid Build Coastguard Worker } 955*795d594fSAndroid Build Coastguard Worker testReturnValues()956*795d594fSAndroid Build Coastguard Worker private static void testReturnValues() throws Throwable { 957*795d594fSAndroid Build Coastguard Worker Lookup lookup = MethodHandles.lookup(); 958*795d594fSAndroid Build Coastguard Worker 959*795d594fSAndroid Build Coastguard Worker // byte 960*795d594fSAndroid Build Coastguard Worker MethodHandle mhByteValue = 961*795d594fSAndroid Build Coastguard Worker lookup.findVirtual(Byte.class, "byteValue", MethodType.methodType(byte.class)); 962*795d594fSAndroid Build Coastguard Worker assertEquals((byte) -77, (byte) mhByteValue.invokeExact(Byte.valueOf((byte) -77))); 963*795d594fSAndroid Build Coastguard Worker assertEquals((byte) -77, (byte) mhByteValue.invoke(Byte.valueOf((byte) -77))); 964*795d594fSAndroid Build Coastguard Worker 965*795d594fSAndroid Build Coastguard Worker // char 966*795d594fSAndroid Build Coastguard Worker MethodHandle mhCharacterValue = 967*795d594fSAndroid Build Coastguard Worker lookup.findStaticGetter(Character.class, "MAX_SURROGATE", char.class); 968*795d594fSAndroid Build Coastguard Worker assertEquals(Character.MAX_SURROGATE, (char) mhCharacterValue.invokeExact()); 969*795d594fSAndroid Build Coastguard Worker assertEquals(Character.MAX_SURROGATE, (char) mhCharacterValue.invoke()); 970*795d594fSAndroid Build Coastguard Worker 971*795d594fSAndroid Build Coastguard Worker // double 972*795d594fSAndroid Build Coastguard Worker MethodHandle mhSin = 973*795d594fSAndroid Build Coastguard Worker lookup.findStatic( 974*795d594fSAndroid Build Coastguard Worker Math.class, "sin", MethodType.methodType(double.class, double.class)); 975*795d594fSAndroid Build Coastguard Worker for (double i = -Math.PI; i <= Math.PI; i += Math.PI / 8) { 976*795d594fSAndroid Build Coastguard Worker assertEquals(Math.sin(i), (double) mhSin.invokeExact(i)); 977*795d594fSAndroid Build Coastguard Worker assertEquals(Math.sin(i), (double) mhSin.invoke(i)); 978*795d594fSAndroid Build Coastguard Worker } 979*795d594fSAndroid Build Coastguard Worker 980*795d594fSAndroid Build Coastguard Worker // float 981*795d594fSAndroid Build Coastguard Worker MethodHandle mhAbsFloat = 982*795d594fSAndroid Build Coastguard Worker lookup.findStatic( 983*795d594fSAndroid Build Coastguard Worker Math.class, "abs", MethodType.methodType(float.class, float.class)); 984*795d594fSAndroid Build Coastguard Worker assertEquals(Math.abs(-3.3e6f), (float) mhAbsFloat.invokeExact(-3.3e6f)); 985*795d594fSAndroid Build Coastguard Worker assertEquals(Math.abs(-3.3e6f), (float) mhAbsFloat.invoke(-3.3e6f)); 986*795d594fSAndroid Build Coastguard Worker 987*795d594fSAndroid Build Coastguard Worker // int 988*795d594fSAndroid Build Coastguard Worker MethodHandle mhAbsInt = 989*795d594fSAndroid Build Coastguard Worker lookup.findStatic(Math.class, "abs", MethodType.methodType(int.class, int.class)); 990*795d594fSAndroid Build Coastguard Worker assertEquals(Math.abs(-1000), (int) mhAbsInt.invokeExact(-1000)); 991*795d594fSAndroid Build Coastguard Worker assertEquals(Math.abs(-1000), (int) mhAbsInt.invoke(-1000)); 992*795d594fSAndroid Build Coastguard Worker 993*795d594fSAndroid Build Coastguard Worker // long 994*795d594fSAndroid Build Coastguard Worker MethodHandle mhMaxLong = 995*795d594fSAndroid Build Coastguard Worker lookup.findStatic( 996*795d594fSAndroid Build Coastguard Worker Math.class, 997*795d594fSAndroid Build Coastguard Worker "max", 998*795d594fSAndroid Build Coastguard Worker MethodType.methodType(long.class, long.class, long.class)); 999*795d594fSAndroid Build Coastguard Worker assertEquals( 1000*795d594fSAndroid Build Coastguard Worker Long.MAX_VALUE, (long) mhMaxLong.invokeExact(Long.MAX_VALUE, Long.MAX_VALUE / 2)); 1001*795d594fSAndroid Build Coastguard Worker assertEquals(Long.MAX_VALUE, (long) mhMaxLong.invoke(Long.MAX_VALUE, Long.MAX_VALUE / 2)); 1002*795d594fSAndroid Build Coastguard Worker assertEquals(0x0123456789abcdefL, (long) mhMaxLong.invokeExact(0x0123456789abcdefL, 0L)); 1003*795d594fSAndroid Build Coastguard Worker assertEquals(0x0123456789abcdefL, (long) mhMaxLong.invoke(0x0123456789abcdefL, 0L)); 1004*795d594fSAndroid Build Coastguard Worker 1005*795d594fSAndroid Build Coastguard Worker // ref 1006*795d594fSAndroid Build Coastguard Worker MethodHandle mhShortValueOf = 1007*795d594fSAndroid Build Coastguard Worker lookup.findStatic( 1008*795d594fSAndroid Build Coastguard Worker Short.class, "valueOf", MethodType.methodType(Short.class, short.class)); 1009*795d594fSAndroid Build Coastguard Worker assertEquals( 1010*795d594fSAndroid Build Coastguard Worker (short) -7890, ((Short) mhShortValueOf.invokeExact((short) -7890)).shortValue()); 1011*795d594fSAndroid Build Coastguard Worker assertEquals((short) -7890, ((Short) mhShortValueOf.invoke((short) -7890)).shortValue()); 1012*795d594fSAndroid Build Coastguard Worker 1013*795d594fSAndroid Build Coastguard Worker // array 1014*795d594fSAndroid Build Coastguard Worker int [] array = {Integer.MIN_VALUE, -1, 0, +1, Integer.MAX_VALUE}; 1015*795d594fSAndroid Build Coastguard Worker MethodHandle mhCopyOf = 1016*795d594fSAndroid Build Coastguard Worker lookup.findStatic( 1017*795d594fSAndroid Build Coastguard Worker Arrays.class, "copyOf", MethodType.methodType(int[].class, int[].class, int.class)); 1018*795d594fSAndroid Build Coastguard Worker assertTrue(Arrays.equals(array, (int[]) mhCopyOf.invokeExact(array, array.length))); 1019*795d594fSAndroid Build Coastguard Worker assertTrue(Arrays.equals(array, (int[]) mhCopyOf.invoke(array, array.length))); 1020*795d594fSAndroid Build Coastguard Worker 1021*795d594fSAndroid Build Coastguard Worker // short 1022*795d594fSAndroid Build Coastguard Worker MethodHandle mhShortValue = 1023*795d594fSAndroid Build Coastguard Worker lookup.findVirtual(Short.class, "shortValue", MethodType.methodType(short.class)); 1024*795d594fSAndroid Build Coastguard Worker assertEquals((short) 12131, (short) mhShortValue.invokeExact(Short.valueOf((short) 12131))); 1025*795d594fSAndroid Build Coastguard Worker assertEquals((short) 12131, (short) mhShortValue.invoke(Short.valueOf((short) 12131))); 1026*795d594fSAndroid Build Coastguard Worker 1027*795d594fSAndroid Build Coastguard Worker // boolean 1028*795d594fSAndroid Build Coastguard Worker MethodHandle mhBooleanValue = 1029*795d594fSAndroid Build Coastguard Worker lookup.findVirtual( 1030*795d594fSAndroid Build Coastguard Worker Boolean.class, "booleanValue", MethodType.methodType(boolean.class)); 1031*795d594fSAndroid Build Coastguard Worker assertEquals(true, (boolean) mhBooleanValue.invokeExact(Boolean.valueOf(true))); 1032*795d594fSAndroid Build Coastguard Worker assertEquals(true, (boolean) mhBooleanValue.invoke(Boolean.valueOf(true))); 1033*795d594fSAndroid Build Coastguard Worker assertEquals(false, (boolean) mhBooleanValue.invokeExact(Boolean.valueOf(false))); 1034*795d594fSAndroid Build Coastguard Worker assertEquals(false, (boolean) mhBooleanValue.invoke(Boolean.valueOf(false))); 1035*795d594fSAndroid Build Coastguard Worker 1036*795d594fSAndroid Build Coastguard Worker System.out.println("testReturnValues done."); 1037*795d594fSAndroid Build Coastguard Worker } 1038*795d594fSAndroid Build Coastguard Worker testReferenceReturnValueConversions()1039*795d594fSAndroid Build Coastguard Worker private static void testReferenceReturnValueConversions() throws Throwable { 1040*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().findStatic( 1041*795d594fSAndroid Build Coastguard Worker Float.class, "valueOf", MethodType.methodType(Float.class, String.class)); 1042*795d594fSAndroid Build Coastguard Worker 1043*795d594fSAndroid Build Coastguard Worker // No conversion 1044*795d594fSAndroid Build Coastguard Worker Float f = (Float) mh.invokeExact("1.375"); 1045*795d594fSAndroid Build Coastguard Worker if (f.floatValue() != 1.375) { 1046*795d594fSAndroid Build Coastguard Worker fail(); 1047*795d594fSAndroid Build Coastguard Worker } 1048*795d594fSAndroid Build Coastguard Worker f = (Float) mh.invoke("1.875"); 1049*795d594fSAndroid Build Coastguard Worker if (f.floatValue() != 1.875) { 1050*795d594fSAndroid Build Coastguard Worker fail(); 1051*795d594fSAndroid Build Coastguard Worker } 1052*795d594fSAndroid Build Coastguard Worker 1053*795d594fSAndroid Build Coastguard Worker // Bad conversion 1054*795d594fSAndroid Build Coastguard Worker try { 1055*795d594fSAndroid Build Coastguard Worker int i = (int) mh.invokeExact("7.77"); 1056*795d594fSAndroid Build Coastguard Worker fail(); 1057*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1058*795d594fSAndroid Build Coastguard Worker 1059*795d594fSAndroid Build Coastguard Worker try { 1060*795d594fSAndroid Build Coastguard Worker int i = (int) mh.invoke("7.77"); 1061*795d594fSAndroid Build Coastguard Worker fail(); 1062*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1063*795d594fSAndroid Build Coastguard Worker 1064*795d594fSAndroid Build Coastguard Worker // Assignment to super-class. 1065*795d594fSAndroid Build Coastguard Worker Number n = (Number) mh.invoke("1.11"); 1066*795d594fSAndroid Build Coastguard Worker try { 1067*795d594fSAndroid Build Coastguard Worker Number o = (Number) mh.invokeExact("1.11"); 1068*795d594fSAndroid Build Coastguard Worker fail(); 1069*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1070*795d594fSAndroid Build Coastguard Worker 1071*795d594fSAndroid Build Coastguard Worker // Assignment to widened boxed primitive class. 1072*795d594fSAndroid Build Coastguard Worker try { 1073*795d594fSAndroid Build Coastguard Worker Double u = (Double) mh.invoke("1.11"); 1074*795d594fSAndroid Build Coastguard Worker fail(); 1075*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1076*795d594fSAndroid Build Coastguard Worker 1077*795d594fSAndroid Build Coastguard Worker try { 1078*795d594fSAndroid Build Coastguard Worker Double v = (Double) mh.invokeExact("1.11"); 1079*795d594fSAndroid Build Coastguard Worker fail(); 1080*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1081*795d594fSAndroid Build Coastguard Worker 1082*795d594fSAndroid Build Coastguard Worker // Unboxed 1083*795d594fSAndroid Build Coastguard Worker float p = (float) mh.invoke("1.11"); 1084*795d594fSAndroid Build Coastguard Worker if (p != 1.11f) { 1085*795d594fSAndroid Build Coastguard Worker fail(); 1086*795d594fSAndroid Build Coastguard Worker } 1087*795d594fSAndroid Build Coastguard Worker 1088*795d594fSAndroid Build Coastguard Worker // Unboxed and widened 1089*795d594fSAndroid Build Coastguard Worker double d = (double) mh.invoke("2.5"); 1090*795d594fSAndroid Build Coastguard Worker if (d != 2.5) { 1091*795d594fSAndroid Build Coastguard Worker fail(); 1092*795d594fSAndroid Build Coastguard Worker } 1093*795d594fSAndroid Build Coastguard Worker 1094*795d594fSAndroid Build Coastguard Worker // Interface 1095*795d594fSAndroid Build Coastguard Worker Comparable<Float> c = (Comparable<Float>) mh.invoke("2.125"); 1096*795d594fSAndroid Build Coastguard Worker if (c.compareTo(new Float(2.125f)) != 0) { 1097*795d594fSAndroid Build Coastguard Worker fail(); 1098*795d594fSAndroid Build Coastguard Worker } 1099*795d594fSAndroid Build Coastguard Worker 1100*795d594fSAndroid Build Coastguard Worker System.out.println("testReferenceReturnValueConversions done."); 1101*795d594fSAndroid Build Coastguard Worker } 1102*795d594fSAndroid Build Coastguard Worker testPrimitiveReturnValueConversions()1103*795d594fSAndroid Build Coastguard Worker private static void testPrimitiveReturnValueConversions() throws Throwable { 1104*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().findStatic( 1105*795d594fSAndroid Build Coastguard Worker Math.class, "min", MethodType.methodType(int.class, int.class, int.class)); 1106*795d594fSAndroid Build Coastguard Worker 1107*795d594fSAndroid Build Coastguard Worker final int SMALL = -8972; 1108*795d594fSAndroid Build Coastguard Worker final int LARGE = 7932529; 1109*795d594fSAndroid Build Coastguard Worker 1110*795d594fSAndroid Build Coastguard Worker // No conversion 1111*795d594fSAndroid Build Coastguard Worker if ((int) mh.invokeExact(LARGE, SMALL) != SMALL) { 1112*795d594fSAndroid Build Coastguard Worker fail(); 1113*795d594fSAndroid Build Coastguard Worker } else if ((int) mh.invoke(LARGE, SMALL) != SMALL) { 1114*795d594fSAndroid Build Coastguard Worker fail(); 1115*795d594fSAndroid Build Coastguard Worker } else if ((int) mh.invokeExact(SMALL, LARGE) != SMALL) { 1116*795d594fSAndroid Build Coastguard Worker fail(); 1117*795d594fSAndroid Build Coastguard Worker } else if ((int) mh.invoke(SMALL, LARGE) != SMALL) { 1118*795d594fSAndroid Build Coastguard Worker fail(); 1119*795d594fSAndroid Build Coastguard Worker } 1120*795d594fSAndroid Build Coastguard Worker 1121*795d594fSAndroid Build Coastguard Worker // int -> long 1122*795d594fSAndroid Build Coastguard Worker try { 1123*795d594fSAndroid Build Coastguard Worker if ((long) mh.invokeExact(LARGE, SMALL) != (long) SMALL) {} 1124*795d594fSAndroid Build Coastguard Worker fail(); 1125*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1126*795d594fSAndroid Build Coastguard Worker 1127*795d594fSAndroid Build Coastguard Worker if ((long) mh.invoke(LARGE, SMALL) != (long) SMALL) { 1128*795d594fSAndroid Build Coastguard Worker fail(); 1129*795d594fSAndroid Build Coastguard Worker } 1130*795d594fSAndroid Build Coastguard Worker 1131*795d594fSAndroid Build Coastguard Worker // int -> short 1132*795d594fSAndroid Build Coastguard Worker try { 1133*795d594fSAndroid Build Coastguard Worker if ((short) mh.invokeExact(LARGE, SMALL) != (short) SMALL) {} 1134*795d594fSAndroid Build Coastguard Worker fail(); 1135*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1136*795d594fSAndroid Build Coastguard Worker 1137*795d594fSAndroid Build Coastguard Worker try { 1138*795d594fSAndroid Build Coastguard Worker if ((short) mh.invoke(LARGE, SMALL) != (short) SMALL) { 1139*795d594fSAndroid Build Coastguard Worker fail(); 1140*795d594fSAndroid Build Coastguard Worker } 1141*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1142*795d594fSAndroid Build Coastguard Worker 1143*795d594fSAndroid Build Coastguard Worker // int -> Integer 1144*795d594fSAndroid Build Coastguard Worker try { 1145*795d594fSAndroid Build Coastguard Worker if (!((Integer) mh.invokeExact(LARGE, SMALL)).equals(new Integer(SMALL))) {} 1146*795d594fSAndroid Build Coastguard Worker fail(); 1147*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1148*795d594fSAndroid Build Coastguard Worker 1149*795d594fSAndroid Build Coastguard Worker if (!((Integer) mh.invoke(LARGE, SMALL)).equals(new Integer(SMALL))) { 1150*795d594fSAndroid Build Coastguard Worker fail(); 1151*795d594fSAndroid Build Coastguard Worker } 1152*795d594fSAndroid Build Coastguard Worker 1153*795d594fSAndroid Build Coastguard Worker // int -> Long 1154*795d594fSAndroid Build Coastguard Worker try { 1155*795d594fSAndroid Build Coastguard Worker Long l = (Long) mh.invokeExact(LARGE, SMALL); 1156*795d594fSAndroid Build Coastguard Worker fail(); 1157*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1158*795d594fSAndroid Build Coastguard Worker 1159*795d594fSAndroid Build Coastguard Worker try { 1160*795d594fSAndroid Build Coastguard Worker Long l = (Long) mh.invoke(LARGE, SMALL); 1161*795d594fSAndroid Build Coastguard Worker fail(); 1162*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1163*795d594fSAndroid Build Coastguard Worker 1164*795d594fSAndroid Build Coastguard Worker // int -> Short 1165*795d594fSAndroid Build Coastguard Worker try { 1166*795d594fSAndroid Build Coastguard Worker Short s = (Short) mh.invokeExact(LARGE, SMALL); 1167*795d594fSAndroid Build Coastguard Worker fail(); 1168*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1169*795d594fSAndroid Build Coastguard Worker 1170*795d594fSAndroid Build Coastguard Worker try { 1171*795d594fSAndroid Build Coastguard Worker Short s = (Short) mh.invoke(LARGE, SMALL); 1172*795d594fSAndroid Build Coastguard Worker fail(); 1173*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1174*795d594fSAndroid Build Coastguard Worker 1175*795d594fSAndroid Build Coastguard Worker // int -> Process 1176*795d594fSAndroid Build Coastguard Worker try { 1177*795d594fSAndroid Build Coastguard Worker Process p = (Process) mh.invokeExact(LARGE, SMALL); 1178*795d594fSAndroid Build Coastguard Worker fail(); 1179*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1180*795d594fSAndroid Build Coastguard Worker 1181*795d594fSAndroid Build Coastguard Worker try { 1182*795d594fSAndroid Build Coastguard Worker Process p = (Process) mh.invoke(LARGE, SMALL); 1183*795d594fSAndroid Build Coastguard Worker fail(); 1184*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1185*795d594fSAndroid Build Coastguard Worker 1186*795d594fSAndroid Build Coastguard Worker // void -> Object 1187*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(System.class, "gc", MethodType.methodType(void.class)); 1188*795d594fSAndroid Build Coastguard Worker Object o = (Object) mh.invoke(); 1189*795d594fSAndroid Build Coastguard Worker if (o != null) fail(); 1190*795d594fSAndroid Build Coastguard Worker 1191*795d594fSAndroid Build Coastguard Worker // void -> long 1192*795d594fSAndroid Build Coastguard Worker long l = (long) mh.invoke(); 1193*795d594fSAndroid Build Coastguard Worker if (l != 0) fail(); 1194*795d594fSAndroid Build Coastguard Worker 1195*795d594fSAndroid Build Coastguard Worker // boolean -> Boolean 1196*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(Boolean.class, "parseBoolean", 1197*795d594fSAndroid Build Coastguard Worker MethodType.methodType(boolean.class, String.class)); 1198*795d594fSAndroid Build Coastguard Worker Boolean z = (Boolean) mh.invoke("True"); 1199*795d594fSAndroid Build Coastguard Worker if (!z.booleanValue()) fail(); 1200*795d594fSAndroid Build Coastguard Worker 1201*795d594fSAndroid Build Coastguard Worker // boolean -> int 1202*795d594fSAndroid Build Coastguard Worker try { 1203*795d594fSAndroid Build Coastguard Worker int unexpectedValue = (int) mh.invoke("True"); 1204*795d594fSAndroid Build Coastguard Worker fail(); 1205*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1206*795d594fSAndroid Build Coastguard Worker 1207*795d594fSAndroid Build Coastguard Worker // boolean -> Integer 1208*795d594fSAndroid Build Coastguard Worker try { 1209*795d594fSAndroid Build Coastguard Worker Integer unexpectedValue = (Integer) mh.invoke("True"); 1210*795d594fSAndroid Build Coastguard Worker fail(); 1211*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1212*795d594fSAndroid Build Coastguard Worker 1213*795d594fSAndroid Build Coastguard Worker // Boolean -> boolean 1214*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(Boolean.class, "valueOf", 1215*795d594fSAndroid Build Coastguard Worker MethodType.methodType(Boolean.class, boolean.class)); 1216*795d594fSAndroid Build Coastguard Worker boolean w = (boolean) mh.invoke(false); 1217*795d594fSAndroid Build Coastguard Worker if (w) fail(); 1218*795d594fSAndroid Build Coastguard Worker 1219*795d594fSAndroid Build Coastguard Worker // Boolean -> int 1220*795d594fSAndroid Build Coastguard Worker try { 1221*795d594fSAndroid Build Coastguard Worker int unexpectedValue = (int) mh.invoke(false); 1222*795d594fSAndroid Build Coastguard Worker fail(); 1223*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1224*795d594fSAndroid Build Coastguard Worker 1225*795d594fSAndroid Build Coastguard Worker // Boolean -> Integer 1226*795d594fSAndroid Build Coastguard Worker try { 1227*795d594fSAndroid Build Coastguard Worker Integer unexpectedValue = (Integer) mh.invoke("True"); 1228*795d594fSAndroid Build Coastguard Worker fail(); 1229*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1230*795d594fSAndroid Build Coastguard Worker 1231*795d594fSAndroid Build Coastguard Worker System.out.println("testPrimitiveReturnValueConversions done."); 1232*795d594fSAndroid Build Coastguard Worker } 1233*795d594fSAndroid Build Coastguard Worker testReturnValueConversions()1234*795d594fSAndroid Build Coastguard Worker public static void testReturnValueConversions() throws Throwable { 1235*795d594fSAndroid Build Coastguard Worker testReferenceReturnValueConversions(); 1236*795d594fSAndroid Build Coastguard Worker testPrimitiveReturnValueConversions(); 1237*795d594fSAndroid Build Coastguard Worker } 1238*795d594fSAndroid Build Coastguard Worker 1239*795d594fSAndroid Build Coastguard Worker public static class BaseVariableArityTester { update(Float f0, Float... floats)1240*795d594fSAndroid Build Coastguard Worker public String update(Float f0, Float... floats) { 1241*795d594fSAndroid Build Coastguard Worker return "base " + f0 + ", " + Arrays.toString(floats); 1242*795d594fSAndroid Build Coastguard Worker } 1243*795d594fSAndroid Build Coastguard Worker } 1244*795d594fSAndroid Build Coastguard Worker 1245*795d594fSAndroid Build Coastguard Worker public static class VariableArityTester extends BaseVariableArityTester { 1246*795d594fSAndroid Build Coastguard Worker private String lastResult; 1247*795d594fSAndroid Build Coastguard Worker 1248*795d594fSAndroid Build Coastguard Worker // Constructors VariableArityTester()1249*795d594fSAndroid Build Coastguard Worker public VariableArityTester() {} VariableArityTester(boolean... booleans)1250*795d594fSAndroid Build Coastguard Worker public VariableArityTester(boolean... booleans) { update(booleans); } VariableArityTester(byte... bytes)1251*795d594fSAndroid Build Coastguard Worker public VariableArityTester(byte... bytes) { update(bytes); } VariableArityTester(char... chars)1252*795d594fSAndroid Build Coastguard Worker public VariableArityTester(char... chars) { update(chars); } VariableArityTester(short... shorts)1253*795d594fSAndroid Build Coastguard Worker public VariableArityTester(short... shorts) { update(shorts); } VariableArityTester(int... ints)1254*795d594fSAndroid Build Coastguard Worker public VariableArityTester(int... ints) { update(ints); } VariableArityTester(long... longs)1255*795d594fSAndroid Build Coastguard Worker public VariableArityTester(long... longs) { update(longs); } VariableArityTester(float... floats)1256*795d594fSAndroid Build Coastguard Worker public VariableArityTester(float... floats) { update(floats); } VariableArityTester(double... doubles)1257*795d594fSAndroid Build Coastguard Worker public VariableArityTester(double... doubles) { update(doubles); } VariableArityTester(Float f0, Float... floats)1258*795d594fSAndroid Build Coastguard Worker public VariableArityTester(Float f0, Float... floats) { update(f0, floats); } VariableArityTester(String s0, String... strings)1259*795d594fSAndroid Build Coastguard Worker public VariableArityTester(String s0, String... strings) { update(s0, strings); } VariableArityTester(char c, Number... numbers)1260*795d594fSAndroid Build Coastguard Worker public VariableArityTester(char c, Number... numbers) { update(c, numbers); } 1261*795d594fSAndroid Build Coastguard Worker @SafeVarargs VariableArityTester(ArrayList<Integer> l0, ArrayList<Integer>... lists)1262*795d594fSAndroid Build Coastguard Worker public VariableArityTester(ArrayList<Integer> l0, ArrayList<Integer>... lists) { 1263*795d594fSAndroid Build Coastguard Worker update(l0, lists); 1264*795d594fSAndroid Build Coastguard Worker } VariableArityTester(List l0, List... lists)1265*795d594fSAndroid Build Coastguard Worker public VariableArityTester(List l0, List... lists) { update(l0, lists); } 1266*795d594fSAndroid Build Coastguard Worker 1267*795d594fSAndroid Build Coastguard Worker // Methods update(boolean... booleans)1268*795d594fSAndroid Build Coastguard Worker public String update(boolean... booleans) { return lastResult = tally(booleans); } update(byte... bytes)1269*795d594fSAndroid Build Coastguard Worker public String update(byte... bytes) { return lastResult = tally(bytes); } update(char... chars)1270*795d594fSAndroid Build Coastguard Worker public String update(char... chars) { return lastResult = tally(chars); } update(short... shorts)1271*795d594fSAndroid Build Coastguard Worker public String update(short... shorts) { return lastResult = tally(shorts); } update(int... ints)1272*795d594fSAndroid Build Coastguard Worker public String update(int... ints) { 1273*795d594fSAndroid Build Coastguard Worker lastResult = tally(ints); 1274*795d594fSAndroid Build Coastguard Worker return lastResult; 1275*795d594fSAndroid Build Coastguard Worker } update(long... longs)1276*795d594fSAndroid Build Coastguard Worker public String update(long... longs) { return lastResult = tally(longs); } update(float... floats)1277*795d594fSAndroid Build Coastguard Worker public String update(float... floats) { return lastResult = tally(floats); } update(double... doubles)1278*795d594fSAndroid Build Coastguard Worker public String update(double... doubles) { return lastResult = tally(doubles); } 1279*795d594fSAndroid Build Coastguard Worker @Override update(Float f0, Float... floats)1280*795d594fSAndroid Build Coastguard Worker public String update(Float f0, Float... floats) { return lastResult = tally(f0, floats); } update(String s0, String... strings)1281*795d594fSAndroid Build Coastguard Worker public String update(String s0, String... strings) { return lastResult = tally(s0, strings); } update(char c, Number... numbers)1282*795d594fSAndroid Build Coastguard Worker public String update(char c, Number... numbers) { return lastResult = tally(c, numbers); } 1283*795d594fSAndroid Build Coastguard Worker @SafeVarargs update(ArrayList<Integer> l0, ArrayList<Integer>... lists)1284*795d594fSAndroid Build Coastguard Worker public final String update(ArrayList<Integer> l0, ArrayList<Integer>... lists) { 1285*795d594fSAndroid Build Coastguard Worker lastResult = tally(l0, lists); 1286*795d594fSAndroid Build Coastguard Worker return lastResult; 1287*795d594fSAndroid Build Coastguard Worker } update(List l0, List... lists)1288*795d594fSAndroid Build Coastguard Worker public String update(List l0, List... lists) { return lastResult = tally(l0, lists); } 1289*795d594fSAndroid Build Coastguard Worker arrayMethod(Object[] o)1290*795d594fSAndroid Build Coastguard Worker public String arrayMethod(Object[] o) { 1291*795d594fSAndroid Build Coastguard Worker return Arrays.deepToString(o); 1292*795d594fSAndroid Build Coastguard Worker } 1293*795d594fSAndroid Build Coastguard Worker lastResult()1294*795d594fSAndroid Build Coastguard Worker public String lastResult() { return lastResult; } 1295*795d594fSAndroid Build Coastguard Worker 1296*795d594fSAndroid Build Coastguard Worker // Static Methods tally(boolean... booleans)1297*795d594fSAndroid Build Coastguard Worker public static String tally(boolean... booleans) { return Arrays.toString(booleans); } tally(byte... bytes)1298*795d594fSAndroid Build Coastguard Worker public static String tally(byte... bytes) { return Arrays.toString(bytes); } tally(char... chars)1299*795d594fSAndroid Build Coastguard Worker public static String tally(char... chars) { return Arrays.toString(chars); } tally(short... shorts)1300*795d594fSAndroid Build Coastguard Worker public static String tally(short... shorts) { return Arrays.toString(shorts); } tally(int... ints)1301*795d594fSAndroid Build Coastguard Worker public static String tally(int... ints) { return Arrays.toString(ints); } tally(long... longs)1302*795d594fSAndroid Build Coastguard Worker public static String tally(long... longs) { return Arrays.toString(longs); } tally(float... floats)1303*795d594fSAndroid Build Coastguard Worker public static String tally(float... floats) { return Arrays.toString(floats); } tally(double... doubles)1304*795d594fSAndroid Build Coastguard Worker public static String tally(double... doubles) { return Arrays.toString(doubles); } tally(Float f0, Float... floats)1305*795d594fSAndroid Build Coastguard Worker public static String tally(Float f0, Float... floats) { 1306*795d594fSAndroid Build Coastguard Worker return f0 + ", " + Arrays.toString(floats); 1307*795d594fSAndroid Build Coastguard Worker } tally(String s0, String... strings)1308*795d594fSAndroid Build Coastguard Worker public static String tally(String s0, String... strings) { 1309*795d594fSAndroid Build Coastguard Worker return s0 + ", " + Arrays.toString(strings); 1310*795d594fSAndroid Build Coastguard Worker } tally(char c, Number... numbers)1311*795d594fSAndroid Build Coastguard Worker public static String tally(char c, Number... numbers) { 1312*795d594fSAndroid Build Coastguard Worker return c + ", " + Arrays.toString(numbers); 1313*795d594fSAndroid Build Coastguard Worker } 1314*795d594fSAndroid Build Coastguard Worker @SafeVarargs tally(ArrayList<Integer> l0, ArrayList<Integer>... lists)1315*795d594fSAndroid Build Coastguard Worker public static String tally(ArrayList<Integer> l0, ArrayList<Integer>... lists) { 1316*795d594fSAndroid Build Coastguard Worker return Arrays.toString(l0.toArray()) + ", " + Arrays.deepToString(lists); 1317*795d594fSAndroid Build Coastguard Worker } tally(List l0, List... lists)1318*795d594fSAndroid Build Coastguard Worker public static String tally(List l0, List... lists) { 1319*795d594fSAndroid Build Coastguard Worker return Arrays.deepToString(l0.toArray()) + ", " + Arrays.deepToString(lists); 1320*795d594fSAndroid Build Coastguard Worker } foo(int... ints)1321*795d594fSAndroid Build Coastguard Worker public static void foo(int... ints) { System.out.println(Arrays.toString(ints)); } sumToPrimitive(int... ints)1322*795d594fSAndroid Build Coastguard Worker public static long sumToPrimitive(int... ints) { 1323*795d594fSAndroid Build Coastguard Worker long result = 0; 1324*795d594fSAndroid Build Coastguard Worker for (int i : ints) result += i; 1325*795d594fSAndroid Build Coastguard Worker return result; 1326*795d594fSAndroid Build Coastguard Worker } sumToReference(int... ints)1327*795d594fSAndroid Build Coastguard Worker public static Long sumToReference(int... ints) { 1328*795d594fSAndroid Build Coastguard Worker System.out.println("Hi"); 1329*795d594fSAndroid Build Coastguard Worker return new Long(sumToPrimitive(ints)); 1330*795d594fSAndroid Build Coastguard Worker } lookup()1331*795d594fSAndroid Build Coastguard Worker public static MethodHandles.Lookup lookup() { 1332*795d594fSAndroid Build Coastguard Worker return MethodHandles.lookup(); 1333*795d594fSAndroid Build Coastguard Worker } 1334*795d594fSAndroid Build Coastguard Worker } 1335*795d594fSAndroid Build Coastguard Worker 1336*795d594fSAndroid Build Coastguard Worker // This method only exists to fool Jack's handling of types. See b/32536744. getAsObject(String[] strings)1337*795d594fSAndroid Build Coastguard Worker public static Object getAsObject(String[] strings) { 1338*795d594fSAndroid Build Coastguard Worker return (Object) strings; 1339*795d594fSAndroid Build Coastguard Worker } 1340*795d594fSAndroid Build Coastguard Worker testVariableArity()1341*795d594fSAndroid Build Coastguard Worker public static void testVariableArity() throws Throwable { 1342*795d594fSAndroid Build Coastguard Worker MethodHandle mh; 1343*795d594fSAndroid Build Coastguard Worker VariableArityTester vat = new VariableArityTester(); 1344*795d594fSAndroid Build Coastguard Worker 1345*795d594fSAndroid Build Coastguard Worker assertEquals("[1]", vat.update(1)); 1346*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 1]", vat.update(1, 1)); 1347*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 1, 1]", vat.update(1, 1, 1)); 1348*795d594fSAndroid Build Coastguard Worker 1349*795d594fSAndroid Build Coastguard Worker // Methods - boolean 1350*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1351*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, boolean[].class)); 1352*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1353*795d594fSAndroid Build Coastguard Worker assertFalse(mh.asFixedArity().isVarargsCollector()); 1354*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1355*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(vat, true, false, true)); 1356*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(vat, new boolean[] { true, false, true})); 1357*795d594fSAndroid Build Coastguard Worker assertEquals("[false, true]", mh.invoke(vat, Boolean.valueOf(false), Boolean.valueOf(true))); 1358*795d594fSAndroid Build Coastguard Worker try { 1359*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, true, true, 0); 1360*795d594fSAndroid Build Coastguard Worker fail(); 1361*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1362*795d594fSAndroid Build Coastguard Worker try { 1363*795d594fSAndroid Build Coastguard Worker assertEquals("[false, true]", mh.invoke(vat, Boolean.valueOf(false), (Boolean) null)); 1364*795d594fSAndroid Build Coastguard Worker fail(); 1365*795d594fSAndroid Build Coastguard Worker } catch (NullPointerException e) {} 1366*795d594fSAndroid Build Coastguard Worker 1367*795d594fSAndroid Build Coastguard Worker // Methods - byte 1368*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1369*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, byte[].class)); 1370*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1371*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1372*795d594fSAndroid Build Coastguard Worker assertEquals("[32, 64, 97]", mh.invoke(vat, (byte) 32, Byte.valueOf((byte) 64), (byte) 97)); 1373*795d594fSAndroid Build Coastguard Worker assertEquals("[32, 64, 97]", mh.invoke(vat, new byte[] {(byte) 32, (byte) 64, (byte) 97})); 1374*795d594fSAndroid Build Coastguard Worker try { 1375*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, (byte) 1, Integer.valueOf(3), (byte) 0); 1376*795d594fSAndroid Build Coastguard Worker fail(); 1377*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1378*795d594fSAndroid Build Coastguard Worker 1379*795d594fSAndroid Build Coastguard Worker // Methods - char 1380*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1381*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, char[].class)); 1382*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1383*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1384*795d594fSAndroid Build Coastguard Worker assertEquals("[A, B, C]", mh.invoke(vat, 'A', Character.valueOf('B'), 'C')); 1385*795d594fSAndroid Build Coastguard Worker assertEquals("[W, X, Y, Z]", mh.invoke(vat, new char[] { 'W', 'X', 'Y', 'Z' })); 1386*795d594fSAndroid Build Coastguard Worker 1387*795d594fSAndroid Build Coastguard Worker // Methods - short 1388*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1389*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, short[].class)); 1390*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1391*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1392*795d594fSAndroid Build Coastguard Worker assertEquals("[32767, -32768, 0]", 1393*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, Short.MAX_VALUE, Short.MIN_VALUE, Short.valueOf((short) 0))); 1394*795d594fSAndroid Build Coastguard Worker assertEquals("[1, -1]", mh.invoke(vat, new short[] { (short) 1, (short) -1 })); 1395*795d594fSAndroid Build Coastguard Worker 1396*795d594fSAndroid Build Coastguard Worker // Methods - int 1397*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1398*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, int[].class)); 1399*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1400*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1401*795d594fSAndroid Build Coastguard Worker assertEquals("[0, 2147483647, -2147483648, 0]", 1402*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, Integer.valueOf(0), Integer.MAX_VALUE, Integer.MIN_VALUE, 0)); 1403*795d594fSAndroid Build Coastguard Worker assertEquals("[0, -1, 1, 0]", mh.invoke(vat, new int[] { 0, -1, 1, 0 })); 1404*795d594fSAndroid Build Coastguard Worker 1405*795d594fSAndroid Build Coastguard Worker assertEquals("[5, 4, 3, 2, 1]", (String) mh.invokeExact(vat, new int [] { 5, 4, 3, 2, 1 })); 1406*795d594fSAndroid Build Coastguard Worker try { 1407*795d594fSAndroid Build Coastguard Worker assertEquals("[5, 4, 3, 2, 1]", (String) mh.invokeExact(vat, 5, 4, 3, 2, 1)); 1408*795d594fSAndroid Build Coastguard Worker fail(); 1409*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1410*795d594fSAndroid Build Coastguard Worker assertEquals("[5, 4, 3, 2, 1]", (String) mh.invoke(vat, 5, 4, 3, 2, 1)); 1411*795d594fSAndroid Build Coastguard Worker 1412*795d594fSAndroid Build Coastguard Worker // Methods - long 1413*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1414*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, long[].class)); 1415*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1416*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1417*795d594fSAndroid Build Coastguard Worker assertEquals("[0, 9223372036854775807, -9223372036854775808]", 1418*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, Long.valueOf(0), Long.MAX_VALUE, Long.MIN_VALUE)); 1419*795d594fSAndroid Build Coastguard Worker assertEquals("[0, -1, 1, 0]", mh.invoke(vat, new long[] { 0, -1, 1, 0 })); 1420*795d594fSAndroid Build Coastguard Worker 1421*795d594fSAndroid Build Coastguard Worker // Methods - float 1422*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1423*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, float[].class)); 1424*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1425*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1426*795d594fSAndroid Build Coastguard Worker assertEquals("[0.0, 1.25, -1.25]", 1427*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, 0.0f, Float.valueOf(1.25f), Float.valueOf(-1.25f))); 1428*795d594fSAndroid Build Coastguard Worker assertEquals("[0.0, -1.0, 1.0, 0.0]", 1429*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, new float[] { 0.0f, -1.0f, 1.0f, 0.0f })); 1430*795d594fSAndroid Build Coastguard Worker 1431*795d594fSAndroid Build Coastguard Worker // Methods - double 1432*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1433*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, double[].class)); 1434*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1435*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke(vat)); 1436*795d594fSAndroid Build Coastguard Worker assertEquals("[0.0, 1.25, -1.25]", 1437*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, 0.0, Double.valueOf(1.25), Double.valueOf(-1.25))); 1438*795d594fSAndroid Build Coastguard Worker assertEquals("[0.0, -1.0, 1.0, 0.0]", 1439*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, new double[] { 0.0, -1.0, 1.0, 0.0 })); 1440*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, 0.3f, 1.33, 1.33); 1441*795d594fSAndroid Build Coastguard Worker 1442*795d594fSAndroid Build Coastguard Worker // Methods - String 1443*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup(). 1444*795d594fSAndroid Build Coastguard Worker findVirtual(VariableArityTester.class, "update", 1445*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, String.class, String[].class)); 1446*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1447*795d594fSAndroid Build Coastguard Worker assertEquals("Echidna, []", mh.invoke(vat, "Echidna")); 1448*795d594fSAndroid Build Coastguard Worker assertEquals("Bongo, [Jerboa, Okapi]", 1449*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, "Bongo", "Jerboa", "Okapi")); 1450*795d594fSAndroid Build Coastguard Worker 1451*795d594fSAndroid Build Coastguard Worker // Methods - Float 1452*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup(). 1453*795d594fSAndroid Build Coastguard Worker findVirtual(VariableArityTester.class, "update", 1454*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, Float.class, Float[].class)); 1455*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1456*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1457*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, Float.valueOf(9.99f), 1458*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1459*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), 1460*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1461*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1462*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, Float.valueOf(9.99f), Float.valueOf(0.0f), 1463*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), Float.valueOf(1.1f))); 1464*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1465*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f)); 1466*795d594fSAndroid Build Coastguard Worker try { 1467*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [77.0, 33.0, 64.0]", 1468*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, Float.valueOf(9.99f), 77, 33, 64)); 1469*795d594fSAndroid Build Coastguard Worker fail(); 1470*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1471*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1472*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(vat, Float.valueOf(9.99f), 1473*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1474*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), 1475*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1476*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, null, 1.1]", 1477*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(vat, Float.valueOf(9.99f), 1478*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1479*795d594fSAndroid Build Coastguard Worker null, 1480*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1481*795d594fSAndroid Build Coastguard Worker try { 1482*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1483*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(vat, Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f)); 1484*795d594fSAndroid Build Coastguard Worker fail(); 1485*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1486*795d594fSAndroid Build Coastguard Worker 1487*795d594fSAndroid Build Coastguard Worker // Methods - Number 1488*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup(). 1489*795d594fSAndroid Build Coastguard Worker findVirtual(VariableArityTester.class, "update", 1490*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, char.class, Number[].class)); 1491*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1492*795d594fSAndroid Build Coastguard Worker assertFalse(mh.asFixedArity().isVarargsCollector()); 1493*795d594fSAndroid Build Coastguard Worker assertEquals("x, []", (String) mh.invoke(vat, 'x')); 1494*795d594fSAndroid Build Coastguard Worker assertEquals("x, [3.141]", (String) mh.invoke(vat, 'x', 3.141)); 1495*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, 37]", 1496*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, 'x', null, 3.131, new Integer(37))); 1497*795d594fSAndroid Build Coastguard Worker try { 1498*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, bad, 37]", 1499*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, 'x', null, 3.131, "bad", new Integer(37))); 1500*795d594fSAndroid Build Coastguard Worker assertTrue(false); 1501*795d594fSAndroid Build Coastguard Worker fail(); 1502*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1503*795d594fSAndroid Build Coastguard Worker try { 1504*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, bad, 37]", 1505*795d594fSAndroid Build Coastguard Worker (String) mh.invoke( 1506*795d594fSAndroid Build Coastguard Worker vat, 'x', (Process) null, 3.131, "bad", new Integer(37))); 1507*795d594fSAndroid Build Coastguard Worker assertTrue(false); 1508*795d594fSAndroid Build Coastguard Worker fail(); 1509*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1510*795d594fSAndroid Build Coastguard Worker 1511*795d594fSAndroid Build Coastguard Worker // Methods - an array method that is not variable arity. 1512*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual( 1513*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, "arrayMethod", 1514*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, Object[].class)); 1515*795d594fSAndroid Build Coastguard Worker assertFalse(mh.isVarargsCollector()); 1516*795d594fSAndroid Build Coastguard Worker mh.invoke(vat, new Object[] { "123" }); 1517*795d594fSAndroid Build Coastguard Worker try { 1518*795d594fSAndroid Build Coastguard Worker assertEquals("-", mh.invoke(vat, new Float(3), new Float(4))); 1519*795d594fSAndroid Build Coastguard Worker fail(); 1520*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1521*795d594fSAndroid Build Coastguard Worker mh = mh.asVarargsCollector(Object[].class); 1522*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1523*795d594fSAndroid Build Coastguard Worker assertEquals("[3.0, 4.0]", (String) mh.invoke(vat, new Float(3), new Float(4))); 1524*795d594fSAndroid Build Coastguard Worker 1525*795d594fSAndroid Build Coastguard Worker // Constructors - default 1526*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 1527*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, MethodType.methodType(void.class)); 1528*795d594fSAndroid Build Coastguard Worker assertFalse(mh.isVarargsCollector()); 1529*795d594fSAndroid Build Coastguard Worker 1530*795d594fSAndroid Build Coastguard Worker // Constructors - boolean 1531*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 1532*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, MethodType.methodType(void.class, boolean[].class)); 1533*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1534*795d594fSAndroid Build Coastguard Worker assertEquals("[true, true, false]", 1535*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke(new boolean[] {true, true, false})).lastResult()); 1536*795d594fSAndroid Build Coastguard Worker assertEquals("[true, true, false]", 1537*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke(true, true, false)).lastResult()); 1538*795d594fSAndroid Build Coastguard Worker try { 1539*795d594fSAndroid Build Coastguard Worker assertEquals("[true, true, false]", 1540*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invokeExact(true, true, false)).lastResult()); 1541*795d594fSAndroid Build Coastguard Worker fail(); 1542*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1543*795d594fSAndroid Build Coastguard Worker 1544*795d594fSAndroid Build Coastguard Worker // Constructors - byte 1545*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 1546*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, MethodType.methodType(void.class, byte[].class)); 1547*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1548*795d594fSAndroid Build Coastguard Worker assertEquals("[55, 66, 60]", 1549*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) 1550*795d594fSAndroid Build Coastguard Worker mh.invoke(new byte[] {(byte) 55, (byte) 66, (byte) 60})).lastResult()); 1551*795d594fSAndroid Build Coastguard Worker assertEquals("[55, 66, 60]", 1552*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke( 1553*795d594fSAndroid Build Coastguard Worker (byte) 55, (byte) 66, (byte) 60)).lastResult()); 1554*795d594fSAndroid Build Coastguard Worker try { 1555*795d594fSAndroid Build Coastguard Worker assertEquals("[55, 66, 60]", 1556*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invokeExact( 1557*795d594fSAndroid Build Coastguard Worker (byte) 55, (byte) 66, (byte) 60)).lastResult()); 1558*795d594fSAndroid Build Coastguard Worker fail(); 1559*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1560*795d594fSAndroid Build Coastguard Worker try { 1561*795d594fSAndroid Build Coastguard Worker assertEquals("[3, 3]", 1562*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke( 1563*795d594fSAndroid Build Coastguard Worker new Number[] { Byte.valueOf((byte) 3), (byte) 3})).lastResult()); 1564*795d594fSAndroid Build Coastguard Worker fail(); 1565*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1566*795d594fSAndroid Build Coastguard Worker 1567*795d594fSAndroid Build Coastguard Worker // Constructors - String (have a different path than other reference types). 1568*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 1569*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, MethodType.methodType(void.class, String.class, String[].class)); 1570*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1571*795d594fSAndroid Build Coastguard Worker assertEquals("x, []", ((VariableArityTester) mh.invoke("x")).lastResult()); 1572*795d594fSAndroid Build Coastguard Worker assertEquals("x, [y]", ((VariableArityTester) mh.invoke("x", "y")).lastResult()); 1573*795d594fSAndroid Build Coastguard Worker assertEquals("x, [y, z]", 1574*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke("x", new String[] { "y", "z" })).lastResult()); 1575*795d594fSAndroid Build Coastguard Worker try { 1576*795d594fSAndroid Build Coastguard Worker assertEquals("x, [y]", ((VariableArityTester) mh.invokeExact("x", "y")).lastResult()); 1577*795d594fSAndroid Build Coastguard Worker fail(); 1578*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1579*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, z]", 1580*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke("x", new String[] { null, "z" })).lastResult()); 1581*795d594fSAndroid Build Coastguard Worker 1582*795d594fSAndroid Build Coastguard Worker // Constructors - Number 1583*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findConstructor( 1584*795d594fSAndroid Build Coastguard Worker VariableArityTester.class, MethodType.methodType(void.class, char.class, Number[].class)); 1585*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1586*795d594fSAndroid Build Coastguard Worker assertFalse(mh.asFixedArity().isVarargsCollector()); 1587*795d594fSAndroid Build Coastguard Worker assertEquals("x, []", ((VariableArityTester) mh.invoke('x')).lastResult()); 1588*795d594fSAndroid Build Coastguard Worker assertEquals("x, [3.141]", ((VariableArityTester) mh.invoke('x', 3.141)).lastResult()); 1589*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, 37]", 1590*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke('x', null, 3.131, new Integer(37))).lastResult()); 1591*795d594fSAndroid Build Coastguard Worker try { 1592*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, bad, 37]", 1593*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke( 1594*795d594fSAndroid Build Coastguard Worker 'x', null, 3.131, "bad", new Integer(37))).lastResult()); 1595*795d594fSAndroid Build Coastguard Worker assertTrue(false); 1596*795d594fSAndroid Build Coastguard Worker fail(); 1597*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1598*795d594fSAndroid Build Coastguard Worker try { 1599*795d594fSAndroid Build Coastguard Worker assertEquals("x, [null, 3.131, bad, 37]", 1600*795d594fSAndroid Build Coastguard Worker ((VariableArityTester) mh.invoke( 1601*795d594fSAndroid Build Coastguard Worker 'x', (Process) null, 3.131, "bad", new Integer(37))).lastResult()); 1602*795d594fSAndroid Build Coastguard Worker assertTrue(false); 1603*795d594fSAndroid Build Coastguard Worker fail(); 1604*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1605*795d594fSAndroid Build Coastguard Worker 1606*795d594fSAndroid Build Coastguard Worker // Static Methods - Float 1607*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup(). 1608*795d594fSAndroid Build Coastguard Worker findStatic(VariableArityTester.class, "tally", 1609*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, Float.class, Float[].class)); 1610*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1611*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1612*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(Float.valueOf(9.99f), 1613*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1614*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), 1615*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1616*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1617*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(Float.valueOf(9.99f), Float.valueOf(0.0f), 1618*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), Float.valueOf(1.1f))); 1619*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1620*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f)); 1621*795d594fSAndroid Build Coastguard Worker try { 1622*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [77.0, 33.0, 64.0]", 1623*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(Float.valueOf(9.99f), 77, 33, 64)); 1624*795d594fSAndroid Build Coastguard Worker fail(); 1625*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1626*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1627*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(Float.valueOf(9.99f), 1628*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1629*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), 1630*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1631*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, null, 1.1]", 1632*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(Float.valueOf(9.99f), 1633*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1634*795d594fSAndroid Build Coastguard Worker null, 1635*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1636*795d594fSAndroid Build Coastguard Worker try { 1637*795d594fSAndroid Build Coastguard Worker assertEquals("9.99, [0.0, 0.1, 1.1]", 1638*795d594fSAndroid Build Coastguard Worker (String) mh.invokeExact(Float.valueOf(9.99f), 0.0f, 0.1f, 1.1f)); 1639*795d594fSAndroid Build Coastguard Worker fail(); 1640*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1641*795d594fSAndroid Build Coastguard Worker 1642*795d594fSAndroid Build Coastguard Worker // Special methods - Float 1643*795d594fSAndroid Build Coastguard Worker mh = VariableArityTester.lookup(). 1644*795d594fSAndroid Build Coastguard Worker findSpecial(BaseVariableArityTester.class, "update", 1645*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, Float.class, Float[].class), 1646*795d594fSAndroid Build Coastguard Worker VariableArityTester.class); 1647*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1648*795d594fSAndroid Build Coastguard Worker assertEquals("base 9.99, [0.0, 0.1, 1.1]", 1649*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, 1650*795d594fSAndroid Build Coastguard Worker Float.valueOf(9.99f), 1651*795d594fSAndroid Build Coastguard Worker new Float[] { Float.valueOf(0.0f), 1652*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), 1653*795d594fSAndroid Build Coastguard Worker Float.valueOf(1.1f) })); 1654*795d594fSAndroid Build Coastguard Worker assertEquals("base 9.99, [0.0, 0.1, 1.1]", 1655*795d594fSAndroid Build Coastguard Worker (String) mh.invoke(vat, Float.valueOf(9.99f), Float.valueOf(0.0f), 1656*795d594fSAndroid Build Coastguard Worker Float.valueOf(0.1f), Float.valueOf(1.1f))); 1657*795d594fSAndroid Build Coastguard Worker 1658*795d594fSAndroid Build Coastguard Worker // Return value conversions. 1659*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1660*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, int[].class)); 1661*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 2, 3]", (String) mh.invoke(vat, 1, 2, 3)); 1662*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 2, 3]", (Object) mh.invoke(vat, 1, 2, 3)); 1663*795d594fSAndroid Build Coastguard Worker try { 1664*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 2, 3, 4]", (long) mh.invoke(vat, 1, 2, 3)); 1665*795d594fSAndroid Build Coastguard Worker fail(); 1666*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1667*795d594fSAndroid Build Coastguard Worker assertEquals("[1, 2, 3]", vat.lastResult()); 1668*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "sumToPrimitive", 1669*795d594fSAndroid Build Coastguard Worker MethodType.methodType(long.class, int[].class)); 1670*795d594fSAndroid Build Coastguard Worker assertEquals(10l, (long) mh.invoke(1, 2, 3, 4)); 1671*795d594fSAndroid Build Coastguard Worker assertEquals(Long.valueOf(10l), (Long) mh.invoke(1, 2, 3, 4)); 1672*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "sumToReference", 1673*795d594fSAndroid Build Coastguard Worker MethodType.methodType(Long.class, int[].class)); 1674*795d594fSAndroid Build Coastguard Worker Object o = mh.invoke(1, 2, 3, 4); 1675*795d594fSAndroid Build Coastguard Worker long l = (long) mh.invoke(1, 2, 3, 4); 1676*795d594fSAndroid Build Coastguard Worker assertEquals(10l, (long) mh.invoke(1, 2, 3, 4)); 1677*795d594fSAndroid Build Coastguard Worker assertEquals(Long.valueOf(10l), (Long) mh.invoke(1, 2, 3, 4)); 1678*795d594fSAndroid Build Coastguard Worker try { 1679*795d594fSAndroid Build Coastguard Worker // WrongMethodTypeException should be raised before invoke here. 1680*795d594fSAndroid Build Coastguard Worker System.out.print("Expect Hi here: "); 1681*795d594fSAndroid Build Coastguard Worker assertEquals(Long.valueOf(10l), (Byte) mh.invoke(1, 2, 3, 4)); 1682*795d594fSAndroid Build Coastguard Worker fail(); 1683*795d594fSAndroid Build Coastguard Worker } catch (ClassCastException e) {} 1684*795d594fSAndroid Build Coastguard Worker try { 1685*795d594fSAndroid Build Coastguard Worker // WrongMethodTypeException should be raised before invoke here. 1686*795d594fSAndroid Build Coastguard Worker System.out.println("Don't expect Hi now"); 1687*795d594fSAndroid Build Coastguard Worker byte b = (byte) mh.invoke(1, 2, 3, 4); 1688*795d594fSAndroid Build Coastguard Worker fail(); 1689*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1690*795d594fSAndroid Build Coastguard Worker 1691*795d594fSAndroid Build Coastguard Worker // Return void produces 0 / null. 1692*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findStatic(VariableArityTester.class, "foo", 1693*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, int[].class)); 1694*795d594fSAndroid Build Coastguard Worker assertEquals(null, (Object) mh.invoke(3, 2, 1)); 1695*795d594fSAndroid Build Coastguard Worker assertEquals(0l, (long) mh.invoke(1, 2, 3)); 1696*795d594fSAndroid Build Coastguard Worker 1697*795d594fSAndroid Build Coastguard Worker // Combinators 1698*795d594fSAndroid Build Coastguard Worker mh = MethodHandles.lookup().findVirtual(VariableArityTester.class, "update", 1699*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, boolean[].class)); 1700*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1701*795d594fSAndroid Build Coastguard Worker mh = mh.bindTo(vat); 1702*795d594fSAndroid Build Coastguard Worker assertFalse(mh.isVarargsCollector()); 1703*795d594fSAndroid Build Coastguard Worker mh = mh.asVarargsCollector(boolean[].class); 1704*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1705*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke()); 1706*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(true, false, true)); 1707*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(new boolean[] { true, false, true})); 1708*795d594fSAndroid Build Coastguard Worker assertEquals("[false, true]", mh.invoke(Boolean.valueOf(false), Boolean.valueOf(true))); 1709*795d594fSAndroid Build Coastguard Worker try { 1710*795d594fSAndroid Build Coastguard Worker mh.invoke(true, true, 0); 1711*795d594fSAndroid Build Coastguard Worker fail(); 1712*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1713*795d594fSAndroid Build Coastguard Worker } 1714*795d594fSAndroid Build Coastguard Worker 1715*795d594fSAndroid Build Coastguard Worker // The same tests as the above, except that we use use MethodHandles.bind instead of 1716*795d594fSAndroid Build Coastguard Worker // MethodHandle.bindTo. testVariableArity_MethodHandles_bind()1717*795d594fSAndroid Build Coastguard Worker public static void testVariableArity_MethodHandles_bind() throws Throwable { 1718*795d594fSAndroid Build Coastguard Worker VariableArityTester vat = new VariableArityTester(); 1719*795d594fSAndroid Build Coastguard Worker MethodHandle mh = MethodHandles.lookup().bind(vat, "update", 1720*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class, boolean[].class)); 1721*795d594fSAndroid Build Coastguard Worker assertTrue(mh.isVarargsCollector()); 1722*795d594fSAndroid Build Coastguard Worker 1723*795d594fSAndroid Build Coastguard Worker assertEquals("[]", mh.invoke()); 1724*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(true, false, true)); 1725*795d594fSAndroid Build Coastguard Worker assertEquals("[true, false, true]", mh.invoke(new boolean[] { true, false, true})); 1726*795d594fSAndroid Build Coastguard Worker assertEquals("[false, true]", mh.invoke(Boolean.valueOf(false), Boolean.valueOf(true))); 1727*795d594fSAndroid Build Coastguard Worker 1728*795d594fSAndroid Build Coastguard Worker try { 1729*795d594fSAndroid Build Coastguard Worker mh.invoke(true, true, 0); 1730*795d594fSAndroid Build Coastguard Worker fail(); 1731*795d594fSAndroid Build Coastguard Worker } catch (WrongMethodTypeException e) {} 1732*795d594fSAndroid Build Coastguard Worker } 1733*795d594fSAndroid Build Coastguard Worker testRevealDirect()1734*795d594fSAndroid Build Coastguard Worker public static void testRevealDirect() throws Throwable { 1735*795d594fSAndroid Build Coastguard Worker // Test with a virtual method : 1736*795d594fSAndroid Build Coastguard Worker MethodType type = MethodType.methodType(String.class); 1737*795d594fSAndroid Build Coastguard Worker MethodHandle handle = MethodHandles.lookup().findVirtual( 1738*795d594fSAndroid Build Coastguard Worker UnreflectTester.class, "publicMethod", type); 1739*795d594fSAndroid Build Coastguard Worker 1740*795d594fSAndroid Build Coastguard Worker // Comparisons with an equivalent member obtained via reflection : 1741*795d594fSAndroid Build Coastguard Worker MethodHandleInfo info = MethodHandles.lookup().revealDirect(handle); 1742*795d594fSAndroid Build Coastguard Worker Method meth = UnreflectTester.class.getMethod("publicMethod"); 1743*795d594fSAndroid Build Coastguard Worker 1744*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_invokeVirtual, info.getReferenceKind()); 1745*795d594fSAndroid Build Coastguard Worker assertEquals("publicMethod", info.getName()); 1746*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1747*795d594fSAndroid Build Coastguard Worker assertFalse(info.isVarArgs()); 1748*795d594fSAndroid Build Coastguard Worker assertEquals(meth, info.reflectAs(Method.class, MethodHandles.lookup())); 1749*795d594fSAndroid Build Coastguard Worker assertEquals(type, info.getMethodType()); 1750*795d594fSAndroid Build Coastguard Worker 1751*795d594fSAndroid Build Coastguard Worker // Resolution via a public lookup should fail because the method in question 1752*795d594fSAndroid Build Coastguard Worker // isn't public. 1753*795d594fSAndroid Build Coastguard Worker try { 1754*795d594fSAndroid Build Coastguard Worker info.reflectAs(Method.class, MethodHandles.publicLookup()); 1755*795d594fSAndroid Build Coastguard Worker fail(); 1756*795d594fSAndroid Build Coastguard Worker } catch (IllegalArgumentException expected) { 1757*795d594fSAndroid Build Coastguard Worker } 1758*795d594fSAndroid Build Coastguard Worker 1759*795d594fSAndroid Build Coastguard Worker // Test with a static method : 1760*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findStatic(UnreflectTester.class, 1761*795d594fSAndroid Build Coastguard Worker "publicStaticMethod", 1762*795d594fSAndroid Build Coastguard Worker MethodType.methodType(String.class)); 1763*795d594fSAndroid Build Coastguard Worker 1764*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1765*795d594fSAndroid Build Coastguard Worker meth = UnreflectTester.class.getMethod("publicStaticMethod"); 1766*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_invokeStatic, info.getReferenceKind()); 1767*795d594fSAndroid Build Coastguard Worker assertEquals("publicStaticMethod", info.getName()); 1768*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1769*795d594fSAndroid Build Coastguard Worker assertFalse(info.isVarArgs()); 1770*795d594fSAndroid Build Coastguard Worker assertEquals(meth, info.reflectAs(Method.class, MethodHandles.lookup())); 1771*795d594fSAndroid Build Coastguard Worker assertEquals(type, info.getMethodType()); 1772*795d594fSAndroid Build Coastguard Worker 1773*795d594fSAndroid Build Coastguard Worker // Test with a var-args method : 1774*795d594fSAndroid Build Coastguard Worker type = MethodType.methodType(String.class, String[].class); 1775*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findVirtual(UnreflectTester.class, 1776*795d594fSAndroid Build Coastguard Worker "publicVarArgsMethod", type); 1777*795d594fSAndroid Build Coastguard Worker 1778*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1779*795d594fSAndroid Build Coastguard Worker meth = UnreflectTester.class.getMethod("publicVarArgsMethod", String[].class); 1780*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_invokeVirtual, info.getReferenceKind()); 1781*795d594fSAndroid Build Coastguard Worker assertEquals("publicVarArgsMethod", info.getName()); 1782*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1783*795d594fSAndroid Build Coastguard Worker assertTrue(info.isVarArgs()); 1784*795d594fSAndroid Build Coastguard Worker assertEquals(meth, info.reflectAs(Method.class, MethodHandles.lookup())); 1785*795d594fSAndroid Build Coastguard Worker assertEquals(type, info.getMethodType()); 1786*795d594fSAndroid Build Coastguard Worker 1787*795d594fSAndroid Build Coastguard Worker // Test with a constructor : 1788*795d594fSAndroid Build Coastguard Worker Constructor cons = UnreflectTester.class.getConstructor(String.class, boolean.class); 1789*795d594fSAndroid Build Coastguard Worker type = MethodType.methodType(void.class, String.class, boolean.class); 1790*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findConstructor(UnreflectTester.class, type); 1791*795d594fSAndroid Build Coastguard Worker 1792*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1793*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_newInvokeSpecial, info.getReferenceKind()); 1794*795d594fSAndroid Build Coastguard Worker assertEquals("<init>", info.getName()); 1795*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1796*795d594fSAndroid Build Coastguard Worker assertFalse(info.isVarArgs()); 1797*795d594fSAndroid Build Coastguard Worker assertEquals(cons, info.reflectAs(Constructor.class, MethodHandles.lookup())); 1798*795d594fSAndroid Build Coastguard Worker assertEquals(type, info.getMethodType()); 1799*795d594fSAndroid Build Coastguard Worker 1800*795d594fSAndroid Build Coastguard Worker // Test with a static field : 1801*795d594fSAndroid Build Coastguard Worker Field field = UnreflectTester.class.getField("publicStaticField"); 1802*795d594fSAndroid Build Coastguard Worker 1803*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findStaticSetter( 1804*795d594fSAndroid Build Coastguard Worker UnreflectTester.class, "publicStaticField", String.class); 1805*795d594fSAndroid Build Coastguard Worker 1806*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1807*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_putStatic, info.getReferenceKind()); 1808*795d594fSAndroid Build Coastguard Worker assertEquals("publicStaticField", info.getName()); 1809*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1810*795d594fSAndroid Build Coastguard Worker assertFalse(info.isVarArgs()); 1811*795d594fSAndroid Build Coastguard Worker assertEquals(field, info.reflectAs(Field.class, MethodHandles.lookup())); 1812*795d594fSAndroid Build Coastguard Worker assertEquals(MethodType.methodType(void.class, String.class), info.getMethodType()); 1813*795d594fSAndroid Build Coastguard Worker 1814*795d594fSAndroid Build Coastguard Worker // Test with a setter on the same field, the type of the handle should change 1815*795d594fSAndroid Build Coastguard Worker // but everything else must remain the same. 1816*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findStaticGetter( 1817*795d594fSAndroid Build Coastguard Worker UnreflectTester.class, "publicStaticField", String.class); 1818*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1819*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_getStatic, info.getReferenceKind()); 1820*795d594fSAndroid Build Coastguard Worker assertEquals(field, info.reflectAs(Field.class, MethodHandles.lookup())); 1821*795d594fSAndroid Build Coastguard Worker assertEquals(MethodType.methodType(String.class), info.getMethodType()); 1822*795d594fSAndroid Build Coastguard Worker 1823*795d594fSAndroid Build Coastguard Worker // Test with an instance field : 1824*795d594fSAndroid Build Coastguard Worker field = UnreflectTester.class.getField("publicField"); 1825*795d594fSAndroid Build Coastguard Worker 1826*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findSetter( 1827*795d594fSAndroid Build Coastguard Worker UnreflectTester.class, "publicField", String.class); 1828*795d594fSAndroid Build Coastguard Worker 1829*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1830*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_putField, info.getReferenceKind()); 1831*795d594fSAndroid Build Coastguard Worker assertEquals("publicField", info.getName()); 1832*795d594fSAndroid Build Coastguard Worker assertTrue(UnreflectTester.class == info.getDeclaringClass()); 1833*795d594fSAndroid Build Coastguard Worker assertFalse(info.isVarArgs()); 1834*795d594fSAndroid Build Coastguard Worker assertEquals(field, info.reflectAs(Field.class, MethodHandles.lookup())); 1835*795d594fSAndroid Build Coastguard Worker assertEquals(MethodType.methodType(void.class, String.class), info.getMethodType()); 1836*795d594fSAndroid Build Coastguard Worker 1837*795d594fSAndroid Build Coastguard Worker // Test with a setter on the same field, the type of the handle should change 1838*795d594fSAndroid Build Coastguard Worker // but everything else must remain the same. 1839*795d594fSAndroid Build Coastguard Worker handle = MethodHandles.lookup().findGetter( 1840*795d594fSAndroid Build Coastguard Worker UnreflectTester.class, "publicField", String.class); 1841*795d594fSAndroid Build Coastguard Worker info = MethodHandles.lookup().revealDirect(handle); 1842*795d594fSAndroid Build Coastguard Worker assertEquals(MethodHandleInfo.REF_getField, info.getReferenceKind()); 1843*795d594fSAndroid Build Coastguard Worker assertEquals(field, info.reflectAs(Field.class, MethodHandles.lookup())); 1844*795d594fSAndroid Build Coastguard Worker assertEquals(MethodType.methodType(String.class), info.getMethodType()); 1845*795d594fSAndroid Build Coastguard Worker } 1846*795d594fSAndroid Build Coastguard Worker testReflectiveCalls()1847*795d594fSAndroid Build Coastguard Worker public static void testReflectiveCalls() throws Throwable { 1848*795d594fSAndroid Build Coastguard Worker String[] methodNames = { "invoke", "invokeExact" }; 1849*795d594fSAndroid Build Coastguard Worker for (String methodName : methodNames) { 1850*795d594fSAndroid Build Coastguard Worker Method invokeMethod = MethodHandle.class.getMethod(methodName, Object[].class); 1851*795d594fSAndroid Build Coastguard Worker MethodHandle instance = 1852*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findVirtual(java.io.PrintStream.class, "println", 1853*795d594fSAndroid Build Coastguard Worker MethodType.methodType(void.class, String.class)); 1854*795d594fSAndroid Build Coastguard Worker try { 1855*795d594fSAndroid Build Coastguard Worker invokeMethod.invoke(instance, new Object[] { new Object[] { Integer.valueOf(1) } } ); 1856*795d594fSAndroid Build Coastguard Worker fail(); 1857*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ite) { 1858*795d594fSAndroid Build Coastguard Worker assertEquals(ite.getCause().getClass(), UnsupportedOperationException.class); 1859*795d594fSAndroid Build Coastguard Worker } 1860*795d594fSAndroid Build Coastguard Worker } 1861*795d594fSAndroid Build Coastguard Worker } 1862*795d594fSAndroid Build Coastguard Worker testInterfaceSpecial()1863*795d594fSAndroid Build Coastguard Worker public static void testInterfaceSpecial() throws Throwable { 1864*795d594fSAndroid Build Coastguard Worker final Method acceptMethod = Consumer.class.getDeclaredMethod("accept", Object.class); 1865*795d594fSAndroid Build Coastguard Worker final Method andThenMethod = Consumer.class.getDeclaredMethod("andThen", Consumer.class); 1866*795d594fSAndroid Build Coastguard Worker // Proxies 1867*795d594fSAndroid Build Coastguard Worker Consumer<Object> c = (Consumer<Object>)Proxy.newProxyInstance( 1868*795d594fSAndroid Build Coastguard Worker Main.class.getClassLoader(), 1869*795d594fSAndroid Build Coastguard Worker new Class<?>[] { Consumer.class }, 1870*795d594fSAndroid Build Coastguard Worker (p, m, a) -> { 1871*795d594fSAndroid Build Coastguard Worker System.out.println("Trying to call " + m); 1872*795d594fSAndroid Build Coastguard Worker if (m.equals(andThenMethod)) { 1873*795d594fSAndroid Build Coastguard Worker List<Object> args = a == null ? Collections.EMPTY_LIST : Arrays.asList(a); 1874*795d594fSAndroid Build Coastguard Worker return MethodHandles.lookup() 1875*795d594fSAndroid Build Coastguard Worker .findSpecial(Consumer.class, 1876*795d594fSAndroid Build Coastguard Worker m.getName(), 1877*795d594fSAndroid Build Coastguard Worker MethodType.methodType(m.getReturnType(), 1878*795d594fSAndroid Build Coastguard Worker m.getParameterTypes()), 1879*795d594fSAndroid Build Coastguard Worker p.getClass()) 1880*795d594fSAndroid Build Coastguard Worker .bindTo(p) 1881*795d594fSAndroid Build Coastguard Worker .invokeWithArguments(args); 1882*795d594fSAndroid Build Coastguard Worker } else if (m.equals(acceptMethod)) { 1883*795d594fSAndroid Build Coastguard Worker System.out.println("Called accept with " + a[0]); 1884*795d594fSAndroid Build Coastguard Worker } 1885*795d594fSAndroid Build Coastguard Worker return null; 1886*795d594fSAndroid Build Coastguard Worker }); 1887*795d594fSAndroid Build Coastguard Worker c.accept("foo"); 1888*795d594fSAndroid Build Coastguard Worker Consumer<Object> c2 = c.andThen((Object o) -> { System.out.println("and then " + o); }); 1889*795d594fSAndroid Build Coastguard Worker c2.accept("bar"); 1890*795d594fSAndroid Build Coastguard Worker 1891*795d594fSAndroid Build Coastguard Worker // Non-proxies 1892*795d594fSAndroid Build Coastguard Worker Consumer<Object> c3 = new Consumer() { 1893*795d594fSAndroid Build Coastguard Worker public void accept(Object o) { 1894*795d594fSAndroid Build Coastguard Worker System.out.println("Got " + o); 1895*795d594fSAndroid Build Coastguard Worker } 1896*795d594fSAndroid Build Coastguard Worker @Override 1897*795d594fSAndroid Build Coastguard Worker public Consumer<Object> andThen(Consumer c) { 1898*795d594fSAndroid Build Coastguard Worker System.out.println("Ignoring and then"); 1899*795d594fSAndroid Build Coastguard Worker return this; 1900*795d594fSAndroid Build Coastguard Worker } 1901*795d594fSAndroid Build Coastguard Worker }; 1902*795d594fSAndroid Build Coastguard Worker Consumer<Object> c4 = c3.andThen((x) -> { throw new Error("Failed"); }); 1903*795d594fSAndroid Build Coastguard Worker c4.accept("hello"); 1904*795d594fSAndroid Build Coastguard Worker Consumer<Object> andthen = (Object o) -> { System.out.println("Called and then with " + o);}; 1905*795d594fSAndroid Build Coastguard Worker Consumer<Object> c5 = 1906*795d594fSAndroid Build Coastguard Worker (Consumer<Object>)MethodHandles.lookup() 1907*795d594fSAndroid Build Coastguard Worker .findSpecial(Consumer.class, 1908*795d594fSAndroid Build Coastguard Worker andThenMethod.getName(), 1909*795d594fSAndroid Build Coastguard Worker MethodType.methodType( 1910*795d594fSAndroid Build Coastguard Worker andThenMethod.getReturnType(), 1911*795d594fSAndroid Build Coastguard Worker andThenMethod.getParameterTypes()), 1912*795d594fSAndroid Build Coastguard Worker c3.getClass()) 1913*795d594fSAndroid Build Coastguard Worker .bindTo(c3) 1914*795d594fSAndroid Build Coastguard Worker .invoke(andthen); 1915*795d594fSAndroid Build Coastguard Worker c5.accept("hello there"); 1916*795d594fSAndroid Build Coastguard Worker 1917*795d594fSAndroid Build Coastguard Worker // Failures 1918*795d594fSAndroid Build Coastguard Worker MethodHandle abstract_target = 1919*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup() 1920*795d594fSAndroid Build Coastguard Worker .findSpecial(Consumer.class, 1921*795d594fSAndroid Build Coastguard Worker acceptMethod.getName(), 1922*795d594fSAndroid Build Coastguard Worker MethodType.methodType(acceptMethod.getReturnType(), 1923*795d594fSAndroid Build Coastguard Worker acceptMethod.getParameterTypes()), 1924*795d594fSAndroid Build Coastguard Worker c3.getClass()); 1925*795d594fSAndroid Build Coastguard Worker try { 1926*795d594fSAndroid Build Coastguard Worker abstract_target.invoke(c3, "hello"); 1927*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException e) { 1928*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected IAE when invoke-special on an abstract interface method"); 1929*795d594fSAndroid Build Coastguard Worker } 1930*795d594fSAndroid Build Coastguard Worker } 1931*795d594fSAndroid Build Coastguard Worker returnInput(int value)1932*795d594fSAndroid Build Coastguard Worker private static int returnInput(int value) { return value; } returnInput(byte value)1933*795d594fSAndroid Build Coastguard Worker private static byte returnInput(byte value) { return value; } returnInput(char value)1934*795d594fSAndroid Build Coastguard Worker private static char returnInput(char value) { return value; } 1935*795d594fSAndroid Build Coastguard Worker testFastInvoke()1936*795d594fSAndroid Build Coastguard Worker private static void testFastInvoke() throws Throwable { 1937*795d594fSAndroid Build Coastguard Worker // This tests use of invoke() that have different types and require widening, but do not 1938*795d594fSAndroid Build Coastguard Worker // require require an explicit asType() transform. 1939*795d594fSAndroid Build Coastguard Worker MethodHandle mh0 = 1940*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic( 1941*795d594fSAndroid Build Coastguard Worker Main.class, "returnInput", MethodType.methodType(int.class, int.class)); 1942*795d594fSAndroid Build Coastguard Worker assertEquals((byte) 127, (byte) (int) mh0.invoke((byte) 127)); 1943*795d594fSAndroid Build Coastguard Worker assertEquals((byte) -128, (byte) (int) mh0.invoke((byte) -128)); 1944*795d594fSAndroid Build Coastguard Worker assertEquals((short) 127, (short) (int) mh0.invoke((byte) 127)); 1945*795d594fSAndroid Build Coastguard Worker assertEquals((short) -128, (short) (int) mh0.invoke((byte) -128)); 1946*795d594fSAndroid Build Coastguard Worker assertEquals((char) 127, (char) (int) mh0.invoke((byte) 127)); 1947*795d594fSAndroid Build Coastguard Worker assertEquals((char) 65535, (char) (int) mh0.invoke((byte) -1)); 1948*795d594fSAndroid Build Coastguard Worker assertEquals((char) 0, (char) (int) mh0.invoke((char) 0)); 1949*795d594fSAndroid Build Coastguard Worker assertEquals((char) 65535, (char) (int) mh0.invoke((char) 65535)); 1950*795d594fSAndroid Build Coastguard Worker assertEquals((short) 127, (short) (int) mh0.invoke((short) 127)); 1951*795d594fSAndroid Build Coastguard Worker assertEquals((short) -128, (short) (int) mh0.invoke((short) -128)); 1952*795d594fSAndroid Build Coastguard Worker assertEquals((int) 127, (int) mh0.invoke((byte) 127)); 1953*795d594fSAndroid Build Coastguard Worker assertEquals((int) -128, (int) mh0.invoke((byte) -128)); 1954*795d594fSAndroid Build Coastguard Worker assertEquals((int) 127, (int) mh0.invoke((short) 127)); 1955*795d594fSAndroid Build Coastguard Worker assertEquals((int) -128, (int) mh0.invoke((short) -128)); 1956*795d594fSAndroid Build Coastguard Worker assertEquals((int) 0, (int) mh0.invoke((char) 0)); 1957*795d594fSAndroid Build Coastguard Worker assertEquals((int) 65535, (int) mh0.invoke((char) 65535)); 1958*795d594fSAndroid Build Coastguard Worker 1959*795d594fSAndroid Build Coastguard Worker MethodHandle mh1 = 1960*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic( 1961*795d594fSAndroid Build Coastguard Worker Main.class, "returnInput", MethodType.methodType(char.class, char.class)); 1962*795d594fSAndroid Build Coastguard Worker assertEquals((int) 0, (int) mh1.invoke((char) 0)); 1963*795d594fSAndroid Build Coastguard Worker assertEquals((int) 65535, (int) mh1.invoke((char) 65535)); 1964*795d594fSAndroid Build Coastguard Worker 1965*795d594fSAndroid Build Coastguard Worker MethodHandle mh2 = 1966*795d594fSAndroid Build Coastguard Worker MethodHandles.lookup().findStatic( 1967*795d594fSAndroid Build Coastguard Worker Main.class, "returnInput", MethodType.methodType(byte.class, byte.class)); 1968*795d594fSAndroid Build Coastguard Worker assertEquals((int) -128, (int) mh2.invoke((byte) -128)); 1969*795d594fSAndroid Build Coastguard Worker assertEquals((int) 127, (int) mh2.invoke((byte) 127)); 1970*795d594fSAndroid Build Coastguard Worker assertEquals((short) -128, (short) mh2.invoke((byte) -128)); 1971*795d594fSAndroid Build Coastguard Worker assertEquals((short) 127, (short) mh2.invoke((byte) 127)); 1972*795d594fSAndroid Build Coastguard Worker } 1973*795d594fSAndroid Build Coastguard Worker } 1974