1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @summary basic tests for MethodHandle.invokeWithArguments 26 * @run testng test.java.lang.invoke.InvokeWithArgumentsTest 27 */ 28 29 package test.java.lang.invoke; 30 31 import org.testng.Assert; 32 import org.testng.annotations.Test; 33 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.invoke.WrongMethodTypeException; 37 38 import static java.lang.invoke.MethodType.methodType; 39 40 public class InvokeWithArgumentsTest { 41 static final MethodHandles.Lookup L = MethodHandles.lookup(); 42 arity(Object o1, Object o2, Object... a)43 static Object[] arity(Object o1, Object o2, Object... a) { 44 return a; 45 } 46 47 @Test testArity()48 public void testArity() throws Throwable { 49 MethodHandle mh = L.findStatic(L.lookupClass(), "arity", 50 methodType(Object[].class, Object.class, Object.class, Object[].class)); 51 52 try { 53 mh.invokeWithArguments(""); 54 Assert.fail("WrongMethodTypeException expected"); 55 } catch (WrongMethodTypeException e) {} 56 } 57 passThrough(String... a)58 static Object[] passThrough(String... a) { 59 return a; 60 } 61 pack(Object o, Object... a)62 static Object[] pack(Object o, Object... a) { 63 return a; 64 } 65 66 @Test testArrayNoPassThrough()67 public void testArrayNoPassThrough() throws Throwable { 68 String[] actual = {"A", "B"}; 69 70 MethodHandle mh = L.findStatic(L.lookupClass(), "passThrough", 71 methodType(Object[].class, String[].class)); 72 73 // Note: the actual array is not preserved, the elements will be 74 // unpacked and then packed into a new array before invoking the method 75 // Android-changed: Cast to Object[] to avoid compilation warning. 76 // String[] expected = (String[]) mh.invokeWithArguments(actual); 77 String[] expected = (String[]) mh.invokeWithArguments((Object[]) actual); 78 79 Assert.assertTrue(actual != expected, "Array should not pass through"); 80 Assert.assertEquals(actual, expected, "Array contents should be equal"); 81 } 82 83 @Test testArrayPack()84 public void testArrayPack() throws Throwable { 85 String[] actual = new String[]{"A", "B"}; 86 87 MethodHandle mh = L.findStatic(L.lookupClass(), "pack", 88 methodType(Object[].class, Object.class, Object[].class)); 89 90 // Note: since String[] can be cast to Object, the actual String[] array 91 // will cast to Object become the single element of a new Object[] array 92 Object[] expected = (Object[]) mh.invokeWithArguments("", actual); 93 94 Assert.assertEquals(1, expected.length, "Array should contain just one element"); 95 Assert.assertTrue(actual == expected[0], "Array should pass through"); 96 } 97 intArray(int... a)98 static void intArray(int... a) { 99 } 100 101 @Test testPrimitiveArrayWithNull()102 public void testPrimitiveArrayWithNull() throws Throwable { 103 MethodHandle mh = L.findStatic(L.lookupClass(), "intArray", 104 methodType(void.class, int[].class)); 105 try { 106 mh.invokeWithArguments(null, null); 107 Assert.fail("NullPointerException expected"); 108 } catch (NullPointerException e) {} 109 } 110 111 @Test testPrimitiveArrayWithRef()112 public void testPrimitiveArrayWithRef() throws Throwable { 113 MethodHandle mh = L.findStatic(L.lookupClass(), "intArray", 114 methodType(void.class, int[].class)); 115 try { 116 mh.invokeWithArguments("A", "B"); 117 Assert.fail("ClassCastException expected"); 118 } catch (ClassCastException e) {} 119 } 120 121 numberArray(Number... a)122 static void numberArray(Number... a) { 123 } 124 125 @Test testRefArrayWithCast()126 public void testRefArrayWithCast() throws Throwable { 127 MethodHandle mh = L.findStatic(L.lookupClass(), "numberArray", 128 methodType(void.class, Number[].class)); 129 // All numbers, should not throw 130 mh.invokeWithArguments(1, 1.0, 1.0F, 1L); 131 132 try { 133 mh.invokeWithArguments("A"); 134 Assert.fail("ClassCastException expected"); 135 } catch (ClassCastException e) {} 136 } 137 } 138