test/tools/javac/lambda/methodReference/SamConversion.java

changeset 1415
01c9d4161882
child 1435
9b26c96f5138
equal deleted inserted replaced
1414:843d3b191773 1415:01c9d4161882
1 /*
2 * Copyright (c) 2012, 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 8003280
27 * @summary Add lambda tests
28 * Test SAM conversion of method references in contexts of assignment, method/constructor argument,
29 * return statement, array initializer, lambda expression body, conditional expression and cast.
30 * @compile SamConversion.java
31 * @run main SamConversion
32 */
33
34 public class SamConversion {
35
36 static int assertionCount = 0;
37
38 static interface Foo {
39 Integer m(int i);
40 }
41
42 static interface Bar {
43 int m(Integer i) throws MyException;
44 }
45
46 private static void assertTrue(boolean b) {
47 assertionCount++;
48 if(!b)
49 throw new AssertionError();
50 }
51
52 private static int test1(Foo foo) {
53 return foo.m(1);
54 }
55
56 private static void test2(Bar bar, int result) {
57 try {
58 assertTrue(bar.m(1) == result);
59 } catch (Exception e){
60 assertTrue(false);
61 }
62 }
63
64 private static Bar test3(int i) {
65 switch (i) {
66 case 0:
67 return A::method1;
68 case 1:
69 return new A()::method2;
70 case 2:
71 return A::method3;
72 case 3:
73 return new A()::method4;
74 case 4:
75 return new A()::method5;
76 case 5:
77 return A::method6;
78 default:
79 return null;
80 }
81 }
82
83 /**
84 * Test SAM conversion of method reference in assignment context
85 */
86 private static void testAssignment() {
87 Foo foo = A::method1; //static reference, parameter type matching and return type matching
88 assertTrue(foo.m(1) == 2);
89
90 foo = new A()::method2; //instance reference, parameter type unboxing and return type boxing
91 assertTrue(foo.m(1) == 3);
92
93 foo = A::method3; //static reference, parameter type matching and return type boxing
94 assertTrue(foo.m(1) == 4);
95
96 foo = new A()::method4; //instance reference, parameter type unboxing and return type matching
97 assertTrue(foo.m(1) == 5);
98
99 foo = new A()::method5; //instance reference, parameter type unboxing and return type matching
100 assertTrue(foo.m(1) == 6);
101
102 Bar bar = A::method1;
103 try {
104 assertTrue(bar.m(1) == 2);
105 } catch (Exception e) {
106 assertTrue(false);
107 }
108
109 bar = new A()::method2;
110 try {
111 assertTrue(bar.m(1) == 3);
112 } catch (Exception e) {
113 assertTrue(false);
114 }
115
116 bar = A::method3;
117 try {
118 assertTrue(bar.m(1) == 4);
119 } catch (Exception e) {
120 assertTrue(false);
121 }
122
123 bar = new A()::method4;
124 try {
125 assertTrue(bar.m(1) == 5);
126 } catch (Exception e) {
127 assertTrue(false);
128 }
129
130 bar = new A()::method5;
131 try {
132 assertTrue(bar.m(1) == 6);
133 } catch (Exception e) {
134 assertTrue(false);
135 }
136
137 bar = new A()::method6;
138 try {
139 bar.m(1);
140 assertTrue(false);
141 } catch (MyException e) {
142 } catch (Exception e) {
143 assertTrue(false);
144 }
145 }
146
147 /**
148 * Test SAM conversion of method reference in method/constructor argument context
149 */
150 private static void testMethodArgument() {
151 assertTrue(test1(A::method1) == 2);
152 assertTrue(test1(new A()::method2) == 3);
153 assertTrue(test1(A::method3) == 4);
154 assertTrue(test1(new A()::method4) == 5);
155 assertTrue(test1(new A()::method5) == 6);
156 test2(A::method1, 2);
157 test2(new A()::method2, 3);
158 test2(A::method3, 4);
159 test2(new A()::method4, 5);
160 test2(new A()::method5, 6);
161 A a = new A(A::method1); //A(Foo f) called
162 assertTrue(a.method2(1) == 11);
163 assertTrue(a.method4(1) == 11);
164 assertTrue(a.method5(1) == 11);
165 A a2 = new A(new A()::method2); //A(Bar b) called
166 assertTrue(a2.method2(1) == 12);
167 assertTrue(a2.method4(1) == 12);
168 assertTrue(a2.method5(1) == 12);
169 }
170
171 /**
172 * Test SAM conversion of method reference in return statement context
173 */
174 private static void testReturnStatement() {
175 Bar bar = test3(0);
176 try {
177 assertTrue(bar.m(1) == 2);
178 } catch (Exception e) {
179 assertTrue(false);
180 }
181 bar = test3(1);
182 try {
183 assertTrue(bar.m(1) == 3);
184 } catch (Exception e) {
185 assertTrue(false);
186 }
187 bar = test3(2);
188 try {
189 assertTrue(bar.m(1) == 4);
190 } catch (Exception e) {
191 assertTrue(false);
192 }
193 bar = test3(3);
194 try {
195 assertTrue(bar.m(1) == 5);
196 } catch (Exception e) {
197 assertTrue(false);
198 }
199 bar = test3(4);
200 try {
201 assertTrue(bar.m(1) == 6);
202 } catch (Exception e) {
203 assertTrue(false);
204 }
205 bar = test3(5);
206 try {
207 bar.m(1);
208 assertTrue(false);
209 } catch (MyException e) {
210 } catch (Exception e) {
211 assertTrue(false);
212 }
213 }
214
215 /**
216 * Test SAM conversion of method reference in cast context
217 */
218 private static void testCast() {
219 assertTrue(((Foo)A::method1).m(1) == 2);
220 try {
221 assertTrue(((Bar)new A()::method2).m(1) == 3);
222 } catch (Exception e) {
223 assertTrue(false);
224 }
225 }
226
227 /**
228 * Test SAM conversion of method reference in array initializer context
229 */
230 private static void testArrayInitializer() {
231 Object[] oarray = {"a", 1, (Foo)A::method3}; //last element need a cast
232 Object[] oarray2 = {"a", 1, (Bar)new A()::method4}; //last element need a cast
233 Foo[] farray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5};
234 Bar[] barray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5, A::method6};
235 }
236
237 /**
238 * Test SAM conversion of method reference in conditional expression context
239 */
240 private static void testConditionalExpression(boolean b) {
241 Foo f = b ? A::method3 : new A()::method5;
242 if(b)
243 assertTrue(f.m(1) == 4);
244 else
245 assertTrue(f.m(1) == 6);
246
247 Bar bar = b ? A::method1 : A::method6;
248 if(b) {
249 try {
250 assertTrue(bar.m(1) == 2);
251 } catch (Exception e) {
252 assertTrue(false);
253 }
254 }
255 else {
256 try {
257 bar.m(1);
258 assertTrue(false);
259 } catch (MyException e) {
260 } catch (Exception e) {
261 assertTrue(false);
262 }
263 }
264 }
265
266 /**
267 * Test SAM conversion of method reference in lambda expression body
268 */
269 private static void testLambdaExpressionBody() {
270 Foo f = n -> ((Foo)A::method3).m(n);
271 assertTrue(f.m(1) == 4);
272
273 Bar b = n -> { return ((Foo)new A()::method5).m(n); };
274 try {
275 assertTrue(b.m(1) == 6);
276 } catch (Exception e) {
277 assertTrue(false);
278 }
279 }
280
281 public static void main(String[] args) {
282 testAssignment();
283 testMethodArgument();
284 testReturnStatement();
285 testCast();
286 testArrayInitializer();
287 testConditionalExpression(true);
288 testConditionalExpression(false);
289 testLambdaExpressionBody();
290
291 assertTrue(assertionCount == 38);
292 }
293
294 static class MyException extends Exception {}
295
296 static class A {
297
298 int value = 0;
299
300 A() {
301 }
302
303 A(Foo f) {
304 value = f.m(9);
305 }
306
307 A(Bar b) {
308 try {
309 value = b.m(9);
310 } catch (MyException e){}
311 }
312
313 static Integer method1(int n) {
314 return n + 1;
315 }
316
317 int method2(Integer n) {
318 return value == 0 ? n + 2 : n + value;
319 }
320
321 static int method3(int n) {
322 return n + 3;
323 }
324
325 Integer method4(Integer n) {
326 return value == 0 ? n + 4 : n + value;
327 }
328
329 Integer method5(Integer n) {
330 return value == 0 ? new Integer(n + 5) : new Integer(n + value);
331 }
332
333 static int method6(Integer n) throws MyException{
334 throw new MyException();
335 }
336 }
337 }

mercurial