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 /* 25 * @test 26 * @bug 8174399 27 * @summary LambdaMetafactory should be able to handle inherited methods as 'implMethod' 28 */ 29 import java.lang.ReflectiveOperationException; 30 import java.lang.invoke.*; 31 32 public class InheritedMethodTest { 33 mt(Class<?> ret, Class<?>... params)34 public static MethodType mt(Class<?> ret, Class<?>... params) { return MethodType.methodType(ret, params); } 35 36 public interface StringFactory { get()37 String get(); 38 } 39 40 public interface I { iString()41 String iString(); 42 } 43 44 public interface J extends I {} 45 46 public static abstract class C implements I {} 47 48 public static class D extends C implements J { toString()49 public String toString() { return "a"; } iString()50 public String iString() { return "b"; } 51 } 52 53 private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); 54 main(String... args)55 public static void main(String... args) throws Throwable { 56 test(lookup.findVirtual(C.class, "toString", mt(String.class)), "a"); 57 test(lookup.findVirtual(C.class, "iString", mt(String.class)), "b"); 58 test(lookup.findVirtual(J.class, "toString", mt(String.class)), "a"); 59 test(lookup.findVirtual(J.class, "iString", mt(String.class)), "b"); 60 test(lookup.findVirtual(I.class, "toString", mt(String.class)), "a"); 61 test(lookup.findVirtual(I.class, "iString", mt(String.class)), "b"); 62 } 63 test(MethodHandle implMethod, String expected)64 static void test(MethodHandle implMethod, String expected) throws Throwable { 65 testMetafactory(implMethod, expected); 66 testAltMetafactory(implMethod, expected); 67 } 68 testMetafactory(MethodHandle implMethod, String expected)69 static void testMetafactory(MethodHandle implMethod, String expected) throws Throwable { 70 CallSite cs = LambdaMetafactory.metafactory(lookup, "get", mt(StringFactory.class, D.class), mt(String.class), 71 implMethod, mt(String.class)); 72 StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(new D()); 73 String actual = factory.get(); 74 if (!expected.equals(actual)) throw new AssertionError("Unexpected result: " + actual); 75 } 76 testAltMetafactory(MethodHandle implMethod, String expected)77 static void testAltMetafactory(MethodHandle implMethod, String expected) throws Throwable { 78 CallSite cs = LambdaMetafactory.altMetafactory(lookup, "get", mt(StringFactory.class, D.class), mt(String.class), 79 implMethod, mt(String.class), LambdaMetafactory.FLAG_SERIALIZABLE); 80 StringFactory factory = (StringFactory) cs.dynamicInvoker().invokeExact(new D()); 81 String actual = factory.get(); 82 if (!expected.equals(actual)) throw new AssertionError("Unexpected result: " + actual); 83 } 84 85 } 86