1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.reflect;
18
19 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNotSame;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertSame;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29
30 import java.awt.Color;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.lang.reflect.Type;
34 import java.nio.file.Files;
35 import java.nio.file.LinkOption;
36 import java.nio.file.Path;
37 import java.util.Arrays;
38 import java.util.Date;
39 import java.util.HashMap;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43
44 import org.apache.commons.lang3.AbstractLangTest;
45 import org.apache.commons.lang3.ArrayUtils;
46 import org.apache.commons.lang3.ClassUtils;
47 import org.apache.commons.lang3.ClassUtils.Interfaces;
48 import org.apache.commons.lang3.math.NumberUtils;
49 import org.apache.commons.lang3.mutable.Mutable;
50 import org.apache.commons.lang3.mutable.MutableObject;
51 import org.apache.commons.lang3.reflect.testbed.Annotated;
52 import org.apache.commons.lang3.reflect.testbed.GenericConsumer;
53 import org.apache.commons.lang3.reflect.testbed.GenericParent;
54 import org.apache.commons.lang3.reflect.testbed.PublicChild;
55 import org.apache.commons.lang3.reflect.testbed.PublicSubBeanOtherPackage;
56 import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
57 import org.apache.commons.lang3.tuple.ImmutablePair;
58 import org.junit.jupiter.api.BeforeEach;
59 import org.junit.jupiter.api.Test;
60 import org.junit.jupiter.params.ParameterizedTest;
61 import org.junit.jupiter.params.provider.ValueSource;
62
63
64
65
66 class MethodUtilsTest extends AbstractLangTest {
67
68 protected abstract static class AbstractGetMatchingMethod implements InterfaceGetMatchingMethod {
69 public abstract void testMethod5(Exception exception);
70 }
71
72 protected abstract static class AbstractGetMatchingMethod2 implements InterfaceGetMatchingMethod {
73 @Override
74 public void testMethod6() { }
75 }
76
77 public static class ChildObject extends ParentObject implements PackagePrivateEmptyInterface {
78 }
79
80 private static final class ConcreteGetMatchingMethod2 extends AbstractGetMatchingMethod2 { }
81
82 private static final class ConcreteGetMatchingMethod22 extends AbstractGetMatchingMethod2 {
83 @Override
84 public void testMethod6() { }
85 }
86
87 private static final class GetMatchingMethodClass {
88
89 public void testMethod() {
90 }
91
92 public void testMethod(final long aLong) {
93 }
94
95 public void testMethod(final Long aLong) {
96 }
97
98 public void testMethod2(final Color aColor) {
99 }
100
101 public void testMethod2(final long aLong) {
102 }
103
104 public void testMethod2(final Long aLong) {
105 }
106
107 public void testMethod3(final long aLong, final Long anotherLong) {
108 }
109
110 public void testMethod3(final Long aLong, final long anotherLong) {
111 }
112
113 public void testMethod3(final Long aLong, final Long anotherLong) {
114 }
115
116 public void testMethod4(final Color aColor1, final Color aColor2) {
117 }
118
119 public void testMethod4(final Long aLong, final Long anotherLong) {
120 }
121 }
122
123 private static final class GetMatchingMethodImpl extends AbstractGetMatchingMethod {
124 @Override
125 public void testMethod5(final Exception exception) {
126 }
127 }
128
129 public static class GrandParentObject {
130 }
131 public static class InheritanceBean {
132 public void testOne(final GrandParentObject obj) {
133 }
134
135 public void testOne(final Object obj) {
136 }
137
138 public void testOne(final ParentObject obj) {
139 }
140
141 public void testTwo(final GrandParentObject obj) {
142 }
143
144 public void testTwo(final Object obj) {
145 }
146
147 public void testTwo(final PackagePrivateEmptyInterface obj) {
148 }
149 }
150
151 interface InterfaceGetMatchingMethod {
152 default void testMethod6() {
153 }
154 }
155 private static final class MethodDescriptor {
156 final Class<?> declaringClass;
157 final String name;
158 final Type[] parameterTypes;
159
160 MethodDescriptor(final Class<?> declaringClass, final String name, final Type... parameterTypes) {
161 this.declaringClass = declaringClass;
162 this.name = name;
163 this.parameterTypes = parameterTypes;
164 }
165 }
166
167 interface PackagePrivateEmptyInterface {
168
169 }
170
171 public static class ParentObject extends GrandParentObject {
172
173 }
174
175 private interface PrivateEmptyInterface {
176
177 }
178
179 public static class PublicImpl1OfPackagePrivateEmptyInterface implements PackagePrivateEmptyInterface {
180
181 }
182
183 public static class PublicImpl2OfPackagePrivateEmptyInterface implements PackagePrivateEmptyInterface {
184
185 }
186
187 public static class TestBean {
188
189 public static String bar() {
190 return "bar()";
191 }
192
193 public static String bar(final double d) {
194 return "bar(double)";
195 }
196
197 public static String bar(final int i) {
198 return "bar(int)";
199 }
200
201 public static String bar(final Integer i) {
202 return "bar(Integer)";
203 }
204
205 public static String bar(final Integer i, final String... s) {
206 return "bar(Integer, String...)";
207 }
208
209 public static String bar(final long... s) {
210 return "bar(long...)";
211 }
212
213 public static String bar(final Object o) {
214 return "bar(Object)";
215 }
216
217 public static String bar(final String s) {
218 return "bar(String)";
219 }
220
221 public static String bar(final String... s) {
222 return "bar(String...)";
223 }
224
225
226
227 public static String numOverload(final Byte... args) {
228 return "Byte...";
229 }
230
231 public static String numOverload(final Double... args) {
232 return "Double...";
233 }
234
235 public static String numOverload(final Float... args) {
236 return "Float...";
237 }
238
239 public static String numOverload(final Integer... args) {
240 return "Integer...";
241 }
242
243 public static String numOverload(final Long... args) {
244 return "Long...";
245 }
246
247 public static String numOverload(final Number... args) {
248 return "Number...";
249 }
250
251 public static String numOverload(final Short... args) {
252 return "Short...";
253 }
254
255 public static void oneParameterStatic(final String s) {
256
257 }
258
259 public static String staticInt(final int intArg) {
260 return "static int";
261 }
262
263 public static String staticIntIntVarArg(final int intArg, final int... args) {
264 return "static int, int...";
265 }
266
267 public static String staticIntLongVarArg(final int intArg, final long... args) {
268 return "static int, long...";
269 }
270
271 public static String staticIntStringVarArg(final int intArg, final String... args) {
272 return "static int, String...";
273 }
274
275 public static String staticPackagePrivateEmptyInterface(final PackagePrivateEmptyInterface... args) {
276 return "static PackagePrivateEmptyInterface...";
277 }
278
279 public static String varOverload(final Boolean... args) {
280 return "Boolean...";
281 }
282
283
284
285 public static String varOverload(final Byte... args) {
286 return "Byte...";
287 }
288
289 public static String varOverload(final Character... args) {
290 return "Character...";
291 }
292
293 public static String varOverload(final Double... args) {
294 return "Double...";
295 }
296
297 public static String varOverload(final Float... args) {
298 return "Float...";
299 }
300
301 public static String varOverload(final Integer... args) {
302 return "Integer...";
303 }
304
305 public static String varOverload(final Long... args) {
306 return "Long...";
307 }
308
309 public static String varOverload(final Number... args) {
310 return "Number...";
311 }
312
313 public static String varOverload(final Object... args) {
314 return "Object...";
315 }
316
317 public static String varOverload(final Short... args) {
318 return "Short...";
319 }
320
321 public static String varOverload(final String... args) {
322 return "String...";
323 }
324
325 public static ImmutablePair<String, Object[]> varOverloadEchoStatic(final Number... args) {
326 return new ImmutablePair<>("Number...", args);
327 }
328
329 public static ImmutablePair<String, Object[]> varOverloadEchoStatic(final String... args) {
330 return new ImmutablePair<>("String...", args);
331 }
332
333 static void verify(final ImmutablePair<String, Object[]> a, final ImmutablePair<String, Object[]> b) {
334 assertEquals(a.getLeft(), b.getLeft());
335 assertArrayEquals(a.getRight(), b.getRight());
336 }
337
338 static void verify(final ImmutablePair<String, Object[]> a, final Object obj) {
339 @SuppressWarnings("unchecked")
340 final ImmutablePair<String, Object[]> pair = (ImmutablePair<String, Object[]>) obj;
341 verify(a, pair);
342 }
343
344 boolean unboxBooleanArray;
345
346 boolean unboxByteArray;
347
348 boolean unboxCharArray;
349
350 boolean unboxDoubleArray;
351
352 boolean unboxFloatArray;
353
354 boolean unboxIntArray;
355
356 boolean unboxLongArray;
357
358 boolean unboxShortArray;
359
360 public String foo() {
361 return "foo()";
362 }
363
364 public String foo(final double d) {
365 return "foo(double)";
366 }
367
368 public String foo(final int i) {
369 return "foo(int)";
370 }
371
372 public String foo(final Integer i) {
373 return "foo(Integer)";
374 }
375
376 public String foo(final Integer i, final String... s) {
377 return "foo(int, String...)";
378 }
379
380 public String foo(final long l) {
381 return "foo(long)";
382 }
383
384 public String foo(final long... l) {
385 return "foo(long...)";
386 }
387
388 public String foo(final Object o) {
389 return "foo(Object)";
390 }
391
392 public String foo(final Object... s) {
393 return "foo(Object...)";
394 }
395
396 public String foo(final String s) {
397 return "foo(String)";
398 }
399
400 public String foo(final String... s) {
401 return "foo(String...)";
402 }
403
404 public String intIntVarArg(final int intArg, final int... args) {
405 return "int, int...";
406 }
407
408 public String intLongVarArg(final int intArg, final long... args) {
409 return "int, long...";
410 }
411
412 public String intStringVarArg(final int intArg, final String... args) {
413 return "int, String...";
414 }
415
416 public void oneParameter(final String s) {
417
418 }
419
420 public String packagePrivateEmptyInterface(final PackagePrivateEmptyInterface... args) {
421 return "PackagePrivateEmptyInterface...";
422 }
423
424 @SuppressWarnings("unused")
425 private String privateStringStuff() {
426 return "privateStringStuff()";
427 }
428
429 @SuppressWarnings("unused")
430 private String privateStringStuff(final double d) {
431 return "privateStringStuff(double)";
432 }
433
434 @SuppressWarnings("unused")
435 private String privateStringStuff(final int i) {
436 return "privateStringStuff(int)";
437 }
438
439 @SuppressWarnings("unused")
440 private String privateStringStuff(final Integer i) {
441 return "privateStringStuff(Integer)";
442 }
443
444 @SuppressWarnings("unused")
445 private String privateStringStuff(final Object s) {
446 return "privateStringStuff(Object)";
447 }
448
449 @SuppressWarnings("unused")
450 private String privateStringStuff(final String s) {
451 return "privateStringStuff(String)";
452 }
453
454 @SuppressWarnings("unused")
455 private void privateStuff() {
456 }
457
458 public boolean[] unboxing(final boolean... values) {
459 unboxBooleanArray = true;
460 return values;
461 }
462
463 public byte[] unboxing(final byte... values) {
464 unboxByteArray = true;
465 return values;
466 }
467
468 public char[] unboxing(final char... values) {
469 unboxCharArray = true;
470 return values;
471 }
472
473 public double[] unboxing(final double... values) {
474 unboxDoubleArray = true;
475 return values;
476 }
477
478 public float[] unboxing(final float... values) {
479 unboxFloatArray = true;
480 return values;
481 }
482
483 public int[] unboxing(final int... values) {
484 unboxIntArray = true;
485 return values;
486 }
487
488 public long[] unboxing(final long... values) {
489 unboxLongArray = true;
490 return values;
491 }
492
493 public short[] unboxing(final short... values) {
494 unboxShortArray = true;
495 return values;
496 }
497
498 public ImmutablePair<String, Object[]> varOverloadEcho(final Number... args) {
499 return new ImmutablePair<>("Number...", args);
500 }
501
502
503
504
505 public ImmutablePair<String, Object[]> varOverloadEcho(final String... args) {
506 return new ImmutablePair<>("String...", args);
507 }
508
509 }
510
511 static class TestBeanSubclass extends TestBean {
512 }
513
514 static class TestBeanWithInterfaces implements PrivateEmptyInterface {
515 public String foo() {
516 return "foo()";
517 }
518 }
519
520 private static class TestMutable implements Mutable<Object> {
521 @Override
522 public Object getValue() {
523 return null;
524 }
525
526 @Override
527 public void setValue(final Object value) {
528 }
529 }
530
531 private static final class TestMutableSubclass extends TestMutable {
532
533 }
534
535 private final Map<Class<?>, Class<?>[]> classCache = new HashMap<>();
536
537 private TestBean testBean;
538
539 private void expectMatchingAccessibleMethodParameterTypes(final Class<?> cls, final String methodName, final Class<?>[] requestTypes,
540 final Class<?>[] actualTypes) {
541 final Method m = MethodUtils.getMatchingAccessibleMethod(cls, methodName, requestTypes);
542 assertNotNull(m, "could not find any matches for " + methodName + " (" + (requestTypes == null ? null : toString(requestTypes)) + ")");
543 assertArrayEquals(actualTypes, m.getParameterTypes(), toString(m.getParameterTypes()) + " not equals " + toString(actualTypes));
544 }
545
546 @BeforeEach
547 public void setUp() {
548 testBean = new TestBean();
549 classCache.clear();
550 }
551
552 private Class<?>[] singletonArray(final Class<?> c) {
553 Class<?>[] result = classCache.get(c);
554 if (result == null) {
555 result = new Class[]{c};
556 classCache.put(c, result);
557 }
558 return result;
559 }
560
561 @Test
562 void testConstructor() throws Exception {
563 assertNotNull(MethodUtils.class.getConstructor().newInstance());
564 }
565
566 @Test
567 void testDistance() throws Exception {
568 final Method distanceMethod = MethodUtils.getMatchingMethod(MethodUtils.class, "distance", Class[].class, Class[].class);
569 distanceMethod.setAccessible(true);
570 assertEquals(-1, distanceMethod.invoke(null, new Class[] { String.class }, new Class[] { Date.class }));
571 assertEquals(0, distanceMethod.invoke(null, new Class[] { Date.class }, new Class[] { Date.class }));
572 assertEquals(1, distanceMethod.invoke(null, new Class[] { Integer.class }, new Class[] { ClassUtils.wrapperToPrimitive(Integer.class) }));
573 assertEquals(2, distanceMethod.invoke(null, new Class[] { Integer.class }, new Class[] { Object.class }));
574 distanceMethod.setAccessible(false);
575 }
576
577 @ParameterizedTest
578 @ValueSource(classes = {TestMutable.class, TestMutableSubclass.class})
579 void testGetAccessibleInterfaceMethod(final Class<?> clazz) throws Exception {
580 final Class<?>[][] p = {ArrayUtils.EMPTY_CLASS_ARRAY, null};
581 for (final Class<?>[] element : p) {
582 final Method method = clazz.getMethod("getValue", element);
583 final Method accessibleMethod = MethodUtils.getAccessibleMethod(method);
584 assertNotSame(accessibleMethod, method);
585 assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
586 final Method accessibleMethod2 = MethodUtils.getAccessibleMethod(clazz, method);
587 assertNotSame(accessibleMethod2, method);
588 assertSame(Mutable.class, accessibleMethod2.getDeclaringClass());
589 }
590 }
591
592 @ParameterizedTest
593 @ValueSource(classes = {TestMutable.class, TestMutableSubclass.class})
594 void testGetAccessibleInterfaceMethodFromDescription(final Class<?> clazz) {
595 final Class<?>[][] p = { ArrayUtils.EMPTY_CLASS_ARRAY, null };
596 for (final Class<?>[] element : p) {
597 final Method accessibleMethod = MethodUtils.getAccessibleMethod(clazz, "getValue", element);
598 assertSame(Mutable.class, accessibleMethod.getDeclaringClass());
599 }
600 }
601
602 @Test
603 void testGetAccessibleMethodInaccessible() throws Exception {
604 assertNull(MethodUtils.getAccessibleMethod(TestBean.class.getDeclaredMethod("privateStuff")));
605 assertNull(MethodUtils.getAccessibleMethod(TestBean.class, TestBean.class.getDeclaredMethod("privateStuff")));
606 assertNull(MethodUtils.getAccessibleMethod(TestBeanSubclass.class, TestBean.class.getDeclaredMethod("privateStuff")));
607 }
608
609 @Test
610 void testGetAccessibleMethodPrivateInterface() throws Exception {
611 final Method expected = TestBeanWithInterfaces.class.getMethod("foo");
612 assertNotNull(expected);
613 final Method actual = MethodUtils.getAccessibleMethod(TestBeanWithInterfaces.class, "foo");
614 assertNull(actual);
615 }
616
617 @Test
618 void testGetAccessibleMethodPublicSub() throws Exception {
619
620 final int modifiers = PackageBean.class.getModifiers();
621 assertFalse(Modifier.isPrivate(modifiers));
622 assertFalse(Modifier.isProtected(modifiers));
623 assertFalse(Modifier.isPublic(modifiers));
624
625 new PublicSubBean().setBar("");
626
627 final PublicSubBean bean = new PublicSubBean();
628 assertEquals(bean.getFoo(), "This is foo", "Start value (foo)");
629 assertEquals(bean.getBar(), "This is bar", "Start value (bar)");
630 bean.setFoo("new foo");
631 bean.setBar("new bar");
632 assertEquals(bean.getFoo(), "new foo", "Set value (foo)");
633 assertEquals(bean.getBar(), "new bar", "Set value (bar)");
634
635
636 MethodUtils.invokeExactMethod(bean, "setFoo", "alpha");
637 assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)");
638 MethodUtils.invokeExactMethod(bean, "setBar", "beta");
639 assertEquals(bean.getBar(), "beta", "Set value (bar:2)");
640
641 Method method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setFoo", String.class);
642 assertNotNull(method, "getAccessibleMethod() setFoo is Null");
643 method.invoke(bean, "1111");
644 assertEquals("1111", bean.getFoo(), "Set value (foo:3)");
645
646 method = MethodUtils.getAccessibleMethod(PublicSubBean.class, "setBar", String.class);
647 assertNotNull(method, "getAccessibleMethod() setBar is Null");
648 method.invoke(bean, "2222");
649 assertEquals("2222", bean.getBar(), "Set value (bar:3)");
650 }
651
652 @Test
653 void testGetAccessibleMethodPublicSubOtherPackage() throws Exception {
654
655 final int modifiers = Class.forName("org.apache.commons.lang3.reflect.testbed.PackageBeanOtherPackage").getModifiers();
656 assertFalse(Modifier.isPrivate(modifiers));
657 assertFalse(Modifier.isProtected(modifiers));
658 assertFalse(Modifier.isPublic(modifiers));
659
660 new PublicSubBeanOtherPackage().setBar("");
661
662 final PublicSubBeanOtherPackage bean = new PublicSubBeanOtherPackage();
663 assertEquals(bean.getFoo(), "This is foo", "Start value (foo)");
664 assertEquals(bean.getBar(), "This is bar", "Start value (bar)");
665 bean.setFoo("new foo");
666 bean.setBar("new bar");
667 assertEquals(bean.getFoo(), "new foo", "Set value (foo)");
668 assertEquals(bean.getBar(), "new bar", "Set value (bar)");
669
670
671 MethodUtils.invokeExactMethod(bean, "setFoo", "alpha");
672 assertEquals(bean.getFoo(), "alpha", "Set value (foo:2)");
673 MethodUtils.invokeExactMethod(bean, "setBar", "beta");
674 assertEquals(bean.getBar(), "beta", "Set value (bar:2)");
675
676 Method method = MethodUtils.getAccessibleMethod(PublicSubBeanOtherPackage.class, "setFoo", String.class);
677 assertNotNull(method, "getAccessibleMethod() setFoo is Null");
678 method.invoke(bean, "1111");
679 assertEquals("1111", bean.getFoo(), "Set value (foo:3)");
680
681 method = MethodUtils.getAccessibleMethod(PublicSubBeanOtherPackage.class, "setBar", String.class);
682 assertNotNull(method, "getAccessibleMethod() setBar is Null");
683 method.invoke(bean, "2222");
684 assertEquals("2222", bean.getBar(), "Set value (bar:3)");
685 }
686
687 @Test
688 void testGetAccessiblePublicMethod() throws Exception {
689 assertSame(MutableObject.class,
690 MethodUtils.getAccessibleMethod(MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY)).getDeclaringClass());
691 assertSame(MutableObject.class, MethodUtils
692 .getAccessibleMethod(MutableObject.class, MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY)).getDeclaringClass());
693 }
694
695 @Test
696 void testGetAccessiblePublicMethodFromDescription() {
697 assertSame(MutableObject.class, MethodUtils.getAccessibleMethod(MutableObject.class, "getValue", ArrayUtils.EMPTY_CLASS_ARRAY).getDeclaringClass());
698 }
699
700 @Test
701 void testGetAnnotationIllegalArgumentException1() {
702 assertNullPointerException(
703 () -> MethodUtils.getAnnotation(FieldUtilsTest.class.getDeclaredMethods()[0], null, true, true));
704 }
705
706 @Test
707 void testGetAnnotationIllegalArgumentException2() {
708 assertNullPointerException(() -> MethodUtils.getAnnotation(null, Annotated.class, true, true));
709 }
710
711 @Test
712 void testGetAnnotationIllegalArgumentException3() {
713 assertNullPointerException(() -> MethodUtils.getAnnotation(null, null, true, true));
714 }
715
716 @Test
717 void testGetAnnotationNotSearchSupersAndNotIgnoreAccess() throws NoSuchMethodException {
718 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"),
719 Annotated.class, false, false));
720 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class,
721 false, false));
722 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"),
723 Annotated.class, false, false));
724 assertNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"),
725 Annotated.class, false, false));
726 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"),
727 Annotated.class, false, false));
728 }
729
730 @Test
731 void testGetAnnotationNotSearchSupersButIgnoreAccess() throws NoSuchMethodException {
732 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"),
733 Annotated.class, false, true));
734 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class,
735 false, true));
736 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"),
737 Annotated.class, false, true));
738 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"),
739 Annotated.class, false, true));
740 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"),
741 Annotated.class, false, true));
742 }
743
744 @Test
745 void testGetAnnotationSearchSupersAndIgnoreAccess() throws NoSuchMethodException {
746 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"),
747 Annotated.class, true, true));
748 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class,
749 true, true));
750 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"),
751 Annotated.class, true, true));
752 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"),
753 Annotated.class, true, true));
754 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"),
755 Annotated.class, true, true));
756
757 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentNotAnnotatedMethod", String.class),
758 Annotated.class, true, true));
759 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentProtectedAnnotatedMethod", String.class),
760 Annotated.class, true, true));
761 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getDeclaredMethod("privateAnnotatedMethod", String.class),
762 Annotated.class, true, true));
763 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("publicAnnotatedMethod", String.class),
764 Annotated.class, true, true));
765 }
766
767 @Test
768 void testGetAnnotationSearchSupersButNotIgnoreAccess() throws NoSuchMethodException {
769 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentNotAnnotatedMethod"),
770 Annotated.class, true, false));
771 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("doIt"), Annotated.class,
772 true, false));
773 assertNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("parentProtectedAnnotatedMethod"),
774 Annotated.class, true, false));
775 assertNull(MethodUtils.getAnnotation(PublicChild.class.getDeclaredMethod("privateAnnotatedMethod"),
776 Annotated.class, true, false));
777 assertNotNull(MethodUtils.getAnnotation(PublicChild.class.getMethod("publicAnnotatedMethod"),
778 Annotated.class, true, false));
779
780 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentNotAnnotatedMethod", String.class),
781 Annotated.class, true, false));
782 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("parentProtectedAnnotatedMethod", String.class),
783 Annotated.class, true, false));
784 assertNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getDeclaredMethod("privateAnnotatedMethod", String.class),
785 Annotated.class, true, false));
786 assertNotNull(MethodUtils.getAnnotation(StringParameterizedChild.class.getMethod("publicAnnotatedMethod", String.class),
787 Annotated.class, true, false));
788 }
789
790 @Test
791 void testGetMatchingAccessibleMethod() {
792 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", ArrayUtils.EMPTY_CLASS_ARRAY, ArrayUtils.EMPTY_CLASS_ARRAY);
793 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", null, ArrayUtils.EMPTY_CLASS_ARRAY);
794 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(String.class), singletonArray(String.class));
795 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Object.class), singletonArray(Object.class));
796 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Boolean.class), singletonArray(Object.class));
797 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Byte.class), singletonArray(Integer.TYPE));
798 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Byte.TYPE), singletonArray(Integer.TYPE));
799 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Short.class), singletonArray(Integer.TYPE));
800 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Short.TYPE), singletonArray(Integer.TYPE));
801 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Character.class), singletonArray(Integer.TYPE));
802 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Character.TYPE), singletonArray(Integer.TYPE));
803 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Integer.class), singletonArray(Integer.class));
804 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Integer.TYPE), singletonArray(Integer.TYPE));
805 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Long.class), singletonArray(Long.TYPE));
806 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Long.TYPE), singletonArray(Long.TYPE));
807 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Float.class), singletonArray(Double.TYPE));
808 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Float.TYPE), singletonArray(Double.TYPE));
809 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.class), singletonArray(Double.TYPE));
810 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.TYPE), singletonArray(Double.TYPE));
811 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", singletonArray(Double.TYPE), singletonArray(Double.TYPE));
812 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", new Class[] { String.class, String.class }, new Class[] { String[].class });
813 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "foo", new Class[] { Integer.TYPE, String.class, String.class },
814 new Class[] { Integer.class, String[].class });
815 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testOne", singletonArray(ParentObject.class), singletonArray(ParentObject.class));
816 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testOne", singletonArray(ChildObject.class), singletonArray(ParentObject.class));
817 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testTwo", singletonArray(ParentObject.class),
818 singletonArray(GrandParentObject.class));
819 expectMatchingAccessibleMethodParameterTypes(InheritanceBean.class, "testTwo", singletonArray(ChildObject.class), singletonArray(PackagePrivateEmptyInterface.class));
820
821 expectMatchingAccessibleMethodParameterTypes(Files.class, "exists", singletonArray(Path.class), new Class[] { Path.class, LinkOption[].class });
822 }
823
824 @Test
825 void testGetMatchingMethod() throws NoSuchMethodException {
826 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod"), GetMatchingMethodClass.class.getMethod("testMethod"));
827 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.TYPE),
828 GetMatchingMethodClass.class.getMethod("testMethod", Long.TYPE));
829 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", Long.class),
830 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
831 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod", (Class<?>) null),
832 GetMatchingMethodClass.class.getMethod("testMethod", Long.class));
833 assertThrows(IllegalStateException.class, () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod2", (Class<?>) null));
834 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, Long.class),
835 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
836 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.class, Long.TYPE),
837 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
838 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", null, Long.TYPE),
839 GetMatchingMethodClass.class.getMethod("testMethod3", Long.class, Long.TYPE));
840 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod3", Long.TYPE, null),
841 GetMatchingMethodClass.class.getMethod("testMethod3", Long.TYPE, Long.class));
842 assertThrows(IllegalStateException.class, () -> MethodUtils.getMatchingMethod(GetMatchingMethodClass.class, "testMethod4", null, null));
843 assertEquals(MethodUtils.getMatchingMethod(GetMatchingMethodImpl.class, "testMethod5", RuntimeException.class),
844 GetMatchingMethodImpl.class.getMethod("testMethod5", Exception.class));
845 assertEquals(GetMatchingMethodImpl.class.getMethod("testMethod6"), MethodUtils.getMatchingMethod(GetMatchingMethodImpl.class, "testMethod6"));
846 assertNullPointerException(() -> MethodUtils.getMatchingMethod(null, "testMethod5", RuntimeException.class));
847 Method testMethod6 = MethodUtils.getMatchingMethod(ConcreteGetMatchingMethod2.class, "testMethod6");
848 assertNotNull(testMethod6);
849 assertEquals(AbstractGetMatchingMethod2.class, testMethod6.getDeclaringClass());
850 testMethod6 = MethodUtils.getMatchingMethod(ConcreteGetMatchingMethod22.class, "testMethod6");
851 assertNotNull(testMethod6);
852 assertEquals(ConcreteGetMatchingMethod22.class, testMethod6.getDeclaringClass());
853 }
854
855 @Test
856 void testGetMethodObject() throws Exception {
857 assertEquals(MutableObject.class.getMethod("getValue", ArrayUtils.EMPTY_CLASS_ARRAY),
858 MethodUtils.getMethodObject(MutableObject.class, "getValue", ArrayUtils.EMPTY_CLASS_ARRAY));
859 assertNull(MethodUtils.getMethodObject(MutableObject.class, "does not exist, at all", ArrayUtils.EMPTY_CLASS_ARRAY));
860 assertNull(MethodUtils.getMethodObject(null, "does not exist, at all", ArrayUtils.EMPTY_CLASS_ARRAY));
861 assertNull(MethodUtils.getMethodObject(null, null, ArrayUtils.EMPTY_CLASS_ARRAY));
862 assertNull(MethodUtils.getMethodObject(MutableObject.class, null, ArrayUtils.EMPTY_CLASS_ARRAY));
863
864 assertNull(MethodUtils.getMethodObject(MutableObject.class, "getValue", new Class[] { null }));
865
866 assertNull(MethodUtils.getMethodObject(MutableObject.class, "equals", new Class[] { null }));
867 assertNull(MethodUtils.getMethodObject(MutableObject.class, "equals", new Class[] { String.class, null, String.class }));
868 }
869
870
871
872
873 @Test
874 @Annotated
875 public void testGetMethodsListWithAnnotation() throws NoSuchMethodException {
876 assertEquals(0, MethodUtils.getMethodsListWithAnnotation(Object.class, Annotated.class).size());
877
878 final List<Method> methodWithAnnotation = MethodUtils.getMethodsListWithAnnotation(MethodUtilsTest.class, Annotated.class);
879 assertEquals(2, methodWithAnnotation.size());
880 assertTrue(methodWithAnnotation.contains(MethodUtilsTest.class.getMethod("testGetMethodsWithAnnotation")));
881 assertTrue(methodWithAnnotation.contains(MethodUtilsTest.class.getMethod("testGetMethodsListWithAnnotation")));
882 }
883
884 @Test
885 void testGetMethodsListWithAnnotationNullPointerException1() {
886 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(FieldUtilsTest.class, null));
887 }
888
889 @Test
890 void testGetMethodsListWithAnnotationNullPointerException2() {
891 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(null, Annotated.class));
892 }
893
894 @Test
895 void testGetMethodsListWithAnnotationNullPointerException3() {
896 assertNullPointerException(() -> MethodUtils.getMethodsListWithAnnotation(null, null));
897 }
898
899 @Test
900 @Annotated
901 public void testGetMethodsWithAnnotation() throws NoSuchMethodException {
902 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class));
903
904 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(MethodUtilsTest.class, Annotated.class);
905 assertEquals(2, methodsWithAnnotation.length);
906 assertTrue(ArrayUtils.contains(methodsWithAnnotation, MethodUtilsTest.class.getMethod("testGetMethodsWithAnnotation")));
907 assertTrue(ArrayUtils.contains(methodsWithAnnotation, MethodUtilsTest.class.getMethod("testGetMethodsListWithAnnotation")));
908 }
909
910 @Test
911 void testGetMethodsWithAnnotationIllegalArgumentException1() {
912 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(FieldUtilsTest.class, null));
913 }
914
915 @Test
916 void testGetMethodsWithAnnotationIllegalArgumentException2() {
917 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(null, Annotated.class));
918 }
919
920 @Test
921 void testGetMethodsWithAnnotationIllegalArgumentException3() {
922 assertNullPointerException(() -> MethodUtils.getMethodsWithAnnotation(null, null));
923 }
924
925 @Test
926 void testGetMethodsWithAnnotationNotSearchSupersAndNotIgnoreAccess() {
927 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, false, false));
928 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, false, false);
929 assertEquals(1, methodsWithAnnotation.length);
930 assertEquals("PublicChild.publicAnnotatedMethod",
931 methodsWithAnnotation[0].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[0].getName());
932 }
933
934 @Test
935 void testGetMethodsWithAnnotationNotSearchSupersButIgnoreAccess() {
936 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, false, true));
937 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, false, true);
938 assertEquals(2, methodsWithAnnotation.length);
939 assertEquals("PublicChild", methodsWithAnnotation[0].getDeclaringClass().getSimpleName());
940 assertEquals("PublicChild", methodsWithAnnotation[1].getDeclaringClass().getSimpleName());
941 assertTrue(methodsWithAnnotation[0].getName().endsWith("AnnotatedMethod"));
942 assertTrue(methodsWithAnnotation[1].getName().endsWith("AnnotatedMethod"));
943 }
944
945 @Test
946 void testGetMethodsWithAnnotationSearchSupersAndIgnoreAccess() {
947 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, true, true));
948 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, true, true);
949 assertEquals(4, methodsWithAnnotation.length);
950 assertEquals("PublicChild", methodsWithAnnotation[0].getDeclaringClass().getSimpleName());
951 assertEquals("PublicChild", methodsWithAnnotation[1].getDeclaringClass().getSimpleName());
952 assertTrue(methodsWithAnnotation[0].getName().endsWith("AnnotatedMethod"));
953 assertTrue(methodsWithAnnotation[1].getName().endsWith("AnnotatedMethod"));
954 assertEquals("Foo.doIt", methodsWithAnnotation[2].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[2].getName());
955 assertEquals("Parent.parentProtectedAnnotatedMethod",
956 methodsWithAnnotation[3].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[3].getName());
957 }
958
959 @Test
960 void testGetMethodsWithAnnotationSearchSupersButNotIgnoreAccess() {
961 assertArrayEquals(new Method[0], MethodUtils.getMethodsWithAnnotation(Object.class, Annotated.class, true, false));
962 final Method[] methodsWithAnnotation = MethodUtils.getMethodsWithAnnotation(PublicChild.class, Annotated.class, true, false);
963 assertEquals(2, methodsWithAnnotation.length);
964 assertEquals("PublicChild.publicAnnotatedMethod",
965 methodsWithAnnotation[0].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[0].getName());
966 assertEquals("Foo.doIt", methodsWithAnnotation[1].getDeclaringClass().getSimpleName() + '.' + methodsWithAnnotation[1].getName());
967 }
968
969 @Test
970 void testGetOverrideHierarchyExcludingInterfaces() {
971 final Method method = MethodUtils.getAccessibleMethod(StringParameterizedChild.class, "consume", String.class);
972 final Iterator<MethodDescriptor> expected =
973 Arrays.asList(new MethodDescriptor(StringParameterizedChild.class, "consume", String.class),
974 new MethodDescriptor(GenericParent.class, "consume", GenericParent.class.getTypeParameters()[0]))
975 .iterator();
976 for (final Method m : MethodUtils.getOverrideHierarchy(method, Interfaces.EXCLUDE)) {
977 assertTrue(expected.hasNext());
978 final MethodDescriptor md = expected.next();
979 assertEquals(md.declaringClass, m.getDeclaringClass());
980 assertEquals(md.name, m.getName());
981 assertEquals(md.parameterTypes.length, m.getParameterTypes().length);
982 for (int i = 0; i < md.parameterTypes.length; i++) {
983 assertTrue(TypeUtils.equals(md.parameterTypes[i], m.getGenericParameterTypes()[i]));
984 }
985 }
986 assertFalse(expected.hasNext());
987 }
988
989 @Test
990 void testGetOverrideHierarchyIncludingInterfaces() {
991 final Method method = MethodUtils.getAccessibleMethod(StringParameterizedChild.class, "consume", String.class);
992 final Iterator<MethodDescriptor> expected =
993 Arrays.asList(new MethodDescriptor(StringParameterizedChild.class, "consume", String.class),
994 new MethodDescriptor(GenericParent.class, "consume", GenericParent.class.getTypeParameters()[0]),
995 new MethodDescriptor(GenericConsumer.class, "consume", GenericConsumer.class.getTypeParameters()[0]))
996 .iterator();
997 for (final Method m : MethodUtils.getOverrideHierarchy(method, Interfaces.INCLUDE)) {
998 assertTrue(expected.hasNext());
999 final MethodDescriptor md = expected.next();
1000 assertEquals(md.declaringClass, m.getDeclaringClass());
1001 assertEquals(md.name, m.getName());
1002 assertEquals(md.parameterTypes.length, m.getParameterTypes().length);
1003 for (int i = 0; i < md.parameterTypes.length; i++) {
1004 assertTrue(TypeUtils.equals(md.parameterTypes[i], m.getGenericParameterTypes()[i]));
1005 }
1006 }
1007 assertFalse(expected.hasNext());
1008 }
1009
1010 @Test
1011 void testInvokeExactMethod() throws Exception {
1012 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1013 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo"));
1014 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", (Object[]) null));
1015 assertEquals("foo()", MethodUtils.invokeExactMethod(testBean, "foo", null, null));
1016 assertEquals("foo(String)", MethodUtils.invokeExactMethod(testBean, "foo", ""));
1017 assertEquals("foo(Object)", MethodUtils.invokeExactMethod(testBean, "foo", new Object()));
1018 assertEquals("foo(Integer)", MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.INTEGER_ONE));
1019 assertEquals("foo(double)", MethodUtils.invokeExactMethod(testBean, "foo", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1020 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.BYTE_ONE));
1021 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", NumberUtils.LONG_ONE));
1022 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, "foo", Boolean.TRUE));
1023 assertThrows(NullPointerException.class, () -> MethodUtils.invokeExactMethod(null, "foo", NumberUtils.BYTE_ONE));
1024 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactMethod(testBean, null, NumberUtils.BYTE_ONE));
1025 assertThrows(NullPointerException.class,
1026 () -> MethodUtils.invokeExactMethod(null, "foo", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1027 assertThrows(NoSuchMethodException.class,
1028 () -> MethodUtils.invokeExactMethod(testBean, null, new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1029 }
1030
1031 @Test
1032 void testInvokeExactStaticMethod() throws Exception {
1033 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1034 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", (Object[]) null));
1035 assertEquals("bar()", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", null, null));
1036 assertEquals("bar(String)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", ""));
1037 assertEquals("bar(Object)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", new Object()));
1038 assertEquals("bar(Integer)", MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE));
1039 assertEquals("bar(double)",
1040 MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", new Object[] { NumberUtils.DOUBLE_ONE }, new Class[] { Double.TYPE }));
1041 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.BYTE_ONE));
1042 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", NumberUtils.LONG_ONE));
1043 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeExactStaticMethod(TestBean.class, "bar", Boolean.TRUE));
1044 }
1045
1046 @Test
1047 void testInvokeJavaVarArgsOverloadingResolution() throws Exception {
1048
1049 assertEquals("Byte...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (byte) 1, (byte) 2));
1050 assertEquals("Short...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (short) 1, (short) 2));
1051 assertEquals("Integer...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 2));
1052 assertEquals("Long...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1L, 2L));
1053 assertEquals("Float...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1f, 2f));
1054 assertEquals("Double...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1d, 2d));
1055 assertEquals("Boolean...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", true, false));
1056
1057 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 1.1));
1058 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 1L));
1059 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1d, 1f));
1060 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (short) 1, (byte) 1));
1061 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", ArrayUtils.EMPTY_OBJECT_ARRAY));
1062 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1063 assertEquals("Number...", MethodUtils.invokeStaticMethod(TestBean.class, "numOverload", (Object[]) ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY));
1064
1065 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, "s"));
1066 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, true));
1067 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1.1, true));
1068 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'c', true));
1069 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 1, 'c'));
1070 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'c', "s"));
1071 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", ArrayUtils.EMPTY_OBJECT_ARRAY));
1072 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1073 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", (Object[]) ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY));
1074 assertEquals("Object...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload"));
1075
1076 assertEquals("String...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", "a", "b"));
1077 assertEquals("Character...", MethodUtils.invokeStaticMethod(TestBean.class, "varOverload", 'a', 'b'));
1078 }
1079
1080 @Test
1081 void testInvokeMethod() throws Exception {
1082 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1083 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo"));
1084 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", (Object[]) null));
1085 assertEquals("foo()", MethodUtils.invokeMethod(testBean, "foo", null, null));
1086 assertEquals("foo(String)", MethodUtils.invokeMethod(testBean, "foo", ""));
1087 assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo", new Object()));
1088 assertEquals("foo(Object)", MethodUtils.invokeMethod(testBean, "foo", Boolean.TRUE));
1089 assertEquals("foo(Integer)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.INTEGER_ONE));
1090 assertEquals("foo(int)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.BYTE_ONE));
1091 assertEquals("foo(long)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.LONG_ONE));
1092 assertEquals("foo(double)", MethodUtils.invokeMethod(testBean, "foo", NumberUtils.DOUBLE_ONE));
1093 assertEquals("foo(String...)", MethodUtils.invokeMethod(testBean, "foo", "a", "b", "c"));
1094 assertEquals("foo(String...)", MethodUtils.invokeMethod(testBean, "foo", "a", "b", "c"));
1095 assertEquals("foo(int, String...)", MethodUtils.invokeMethod(testBean, "foo", 5, "a", "b", "c"));
1096 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", 1L, 2L));
1097 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", 1, 2));
1098 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (byte) 1, (byte) 2));
1099 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (short) 1, (short) 2));
1100 assertEquals("foo(long...)", MethodUtils.invokeMethod(testBean, "foo", (char) 1, (char) 2));
1101 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
1102 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", 17, 23, 42));
1103 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", "x", "y"));
1104 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }), MethodUtils.invokeMethod(testBean, "varOverloadEcho", 17, 23, 42));
1105 assertNullPointerException(() -> MethodUtils.invokeMethod(null, "foo", 1, 2));
1106 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, null, 1, 2));
1107 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(new Object(), "nonExistent", new Object[] { "val" }, new Class<?>[] { null }));
1108 }
1109
1110 @Test
1111 void testInvokeMethod_VarArgsWithNullValues() throws Exception {
1112 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", "a", null, "c"));
1113 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", "a", "b", null));
1114 assertEquals("String...", MethodUtils.invokeMethod(testBean, "varOverload", new String[] { "a" }, new Class<?>[] { String.class }));
1115 assertThrows(NoSuchMethodException.class,
1116 () -> assertEquals("String...", MethodUtils.invokeMethod(testBean, "doesn't exist", new String[] { "a" }, new Class<?>[] { null })));
1117 }
1118
1119 @Test
1120 void testInvokeMethod1PlusVarArgs() throws Exception {
1121
1122 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1));
1123 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s"));
1124 assertEquals("int, String...", MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s1", "s2"));
1125 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intStringVarArg", 1, "s1", 5));
1126
1127 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1));
1128 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, 2L));
1129 assertEquals("int, long...", MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, 2L, 3L));
1130 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, "s1", 5));
1131
1132 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1));
1133 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1, 2));
1134 assertEquals("int, int...", MethodUtils.invokeMethod(testBean, "intIntVarArg", 1, 2, 3));
1135 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "intLongVarArg", 1, "s1", 5));
1136 }
1137
1138 @Test
1139 void testInvokeMethodForceAccessNoArgs() throws Exception {
1140 assertEquals("privateStringStuff()", MethodUtils.invokeMethod(testBean, true, "privateStringStuff"));
1141 }
1142
1143 @Test
1144 void testInvokeMethodForceAccessWithArgs() throws Exception {
1145 assertEquals("privateStringStuff(Integer)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", 5));
1146 assertEquals("privateStringStuff(double)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", 5.0d));
1147 assertEquals("privateStringStuff(String)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", "Hi There"));
1148 assertEquals("privateStringStuff(Object)", MethodUtils.invokeMethod(testBean, true, "privateStringStuff", new Date()));
1149 assertNullPointerException(() -> MethodUtils.invokeMethod(null, true, "privateStringStuff", "Hi There"));
1150 assertNullPointerException(() -> MethodUtils.invokeMethod(testBean, true, null, "Hi There"));
1151 }
1152
1153 @Test
1154 void testInvokeMethodVarArgsNotUniqueResolvable() throws Exception {
1155 assertEquals("Boolean...", MethodUtils.invokeMethod(testBean, "varOverload", new Object[] { null }));
1156 assertEquals("Object...", MethodUtils.invokeMethod(testBean, "varOverload", (Object[]) null));
1157 }
1158
1159 @Test
1160 void testInvokeMethodVarArgsOfInterface() throws Exception {
1161
1162 assertEquals("PackagePrivateEmptyInterface...", MethodUtils.invokeMethod(testBean, "packagePrivateEmptyInterface",
1163 new PublicImpl1OfPackagePrivateEmptyInterface(), new PublicImpl2OfPackagePrivateEmptyInterface()));
1164 assertEquals("PackagePrivateEmptyInterface...", MethodUtils.invokeMethod(testBean, "packagePrivateEmptyInterface", new PackagePrivateEmptyInterface() {
1165
1166 }, new PackagePrivateEmptyInterface() {
1167
1168 }));
1169 }
1170
1171 @Test
1172 void testInvokeMethodVarArgsUnboxingBooleanArray() throws Exception {
1173 final TestBean testBean = new TestBean();
1174 final boolean[] actual = (boolean[]) MethodUtils.invokeMethod(testBean, "unboxing", Boolean.TRUE, Boolean.FALSE);
1175 assertArrayEquals(new boolean[] { true, false }, actual);
1176 assertTrue(testBean.unboxBooleanArray);
1177 }
1178
1179 @Test
1180 void testInvokeMethodVarArgsUnboxingByteArray() throws Exception {
1181 final TestBean testBean = new TestBean();
1182 final byte[] actual = (byte[]) MethodUtils.invokeMethod(testBean, "unboxing", Byte.valueOf((byte) 1), Byte.valueOf((byte) 2));
1183 assertArrayEquals(new byte[] { 1, 2 }, actual);
1184 assertTrue(testBean.unboxByteArray);
1185 }
1186
1187 @Test
1188 void testInvokeMethodVarArgsUnboxingCharArray() throws Exception {
1189 final TestBean testBean = new TestBean();
1190 final char[] actual = (char[]) MethodUtils.invokeMethod(testBean, "unboxing", Character.valueOf((char) 1), Character.valueOf((char) 2));
1191 assertArrayEquals(new char[] { 1, 2 }, actual);
1192 assertTrue(testBean.unboxCharArray);
1193 }
1194
1195 @Test
1196 void testInvokeMethodVarArgsUnboxingDoubleArray() throws Exception {
1197 final TestBean testBean = new TestBean();
1198 final double[] actual = (double[]) MethodUtils.invokeMethod(testBean, "unboxing", Double.valueOf(1), Double.valueOf(2));
1199 assertArrayEquals(new double[] { 1, 2 }, actual);
1200 assertTrue(testBean.unboxDoubleArray);
1201 }
1202
1203 @Test
1204 void testInvokeMethodVarArgsUnboxingFloatArray() throws Exception {
1205 final TestBean testBean = new TestBean();
1206 final float[] actual = (float[]) MethodUtils.invokeMethod(testBean, "unboxing", Float.valueOf(1), Float.valueOf(2));
1207 assertArrayEquals(new float[] { 1, 2 }, actual);
1208 assertTrue(testBean.unboxFloatArray);
1209 }
1210
1211 @Test
1212 void testInvokeMethodVarArgsUnboxingIntArray() throws Exception {
1213 final TestBean testBean = new TestBean();
1214 final int[] actual = (int[]) MethodUtils.invokeMethod(testBean, "unboxing", Integer.valueOf(1), Integer.valueOf(2));
1215 assertArrayEquals(new int[] { 1, 2 }, actual);
1216 assertTrue(testBean.unboxIntArray);
1217 }
1218
1219 @Test
1220 void testInvokeMethodVarArgsUnboxingLongArray() throws Exception {
1221 final TestBean testBean = new TestBean();
1222 final long[] actual = (long[]) MethodUtils.invokeMethod(testBean, "unboxing", Long.valueOf(1), Long.valueOf(2));
1223 assertArrayEquals(new long[] { 1, 2 }, actual);
1224 assertTrue(testBean.unboxLongArray);
1225 }
1226
1227 @Test
1228 void testInvokeMethodVarArgsUnboxingShortArray() throws Exception {
1229 final TestBean testBean = new TestBean();
1230 final short[] actual = (short[]) MethodUtils.invokeMethod(testBean, "unboxing", Short.valueOf((short) 1), Short.valueOf((short) 2));
1231 assertArrayEquals(new short[] { 1, 2 }, actual);
1232 assertTrue(testBean.unboxShortArray);
1233 }
1234
1235 @Test
1236 void testInvokeStaticMethod() throws Exception {
1237 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar"));
1238 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (Object[]) ArrayUtils.EMPTY_CLASS_ARRAY));
1239 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (Object[]) null));
1240 assertEquals("bar()", MethodUtils.invokeStaticMethod(TestBean.class, "bar", null, null));
1241 assertEquals("bar(String)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", ""));
1242 assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", new Object()));
1243 assertEquals("bar(Object)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", Boolean.TRUE));
1244 assertEquals("bar(Integer)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE));
1245 assertEquals("bar(int)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.BYTE_ONE));
1246 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.BYTE_ONE));
1247 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.SHORT_ONE));
1248 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", NumberUtils.INTEGER_ONE));
1249 assertEquals("static int", MethodUtils.invokeStaticMethod(TestBean.class, "staticInt", 'a'));
1250 assertEquals("bar(double)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.DOUBLE_ONE));
1251 assertEquals("bar(String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", "a", "b"));
1252 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", 1L, 2L));
1253 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (byte) 1, (byte) 2));
1254 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", (short) 1, (short) 2));
1255 assertEquals("bar(long...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", 1, 2));
1256 assertEquals("bar(Integer, String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.INTEGER_ONE, "a", "b"));
1257
1258 assertThrows(NoSuchMethodException.class,
1259 () -> assertEquals("bar(Integer, String...)", MethodUtils.invokeStaticMethod(TestBean.class, "bar", NumberUtils.SHORT_ONE, "a", "b")));
1260 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }),
1261 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", "x", "y"));
1262 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }),
1263 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", 17, 23, 42));
1264 TestBean.verify(new ImmutablePair<>("String...", new String[] { "x", "y" }),
1265 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", "x", "y"));
1266 TestBean.verify(new ImmutablePair<>("Number...", new Number[] { 17, 23, 42 }),
1267 MethodUtils.invokeStaticMethod(TestBean.class, "varOverloadEchoStatic", 17, 23, 42));
1268 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeStaticMethod(TestBean.class, "does_not_exist"));
1269 }
1270
1271 @Test
1272 void testInvokeStaticMethod1PlusVarArgs() throws Exception {
1273
1274 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1));
1275 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s"));
1276 assertEquals("static int, String...", MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s1", "s2"));
1277 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeStaticMethod(TestBean.class, "staticIntStringVarArg", 1, "s1", 5));
1278
1279 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1));
1280 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, 2L));
1281 assertEquals("static int, long...", MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, 2L, 3L));
1282 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "staticIntLongVarArg", 1, "s1", 5));
1283
1284 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1));
1285 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, 2));
1286 assertEquals("static int, int...", MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, 2, 3));
1287 assertThrows(NoSuchMethodException.class, () -> MethodUtils.invokeMethod(testBean, "staticIntIntVarArg", 1, "s1", 5));
1288 }
1289
1290 @Test
1291 void testInvokeStaticMethodVarArgsOfInterface() throws Exception {
1292
1293 assertEquals("static PackagePrivateEmptyInterface...", MethodUtils.invokeStaticMethod(TestBean.class, "staticPackagePrivateEmptyInterface",
1294 new PublicImpl1OfPackagePrivateEmptyInterface(), new PublicImpl2OfPackagePrivateEmptyInterface()));
1295 assertEquals("static PackagePrivateEmptyInterface...",
1296 MethodUtils.invokeStaticMethod(TestBean.class, "staticPackagePrivateEmptyInterface", new PackagePrivateEmptyInterface() {
1297
1298 }, new PackagePrivateEmptyInterface() {
1299
1300 }));
1301 }
1302
1303 @Test
1304 void testNullArgument() {
1305 expectMatchingAccessibleMethodParameterTypes(TestBean.class, "oneParameter", singletonArray(null), singletonArray(String.class));
1306 }
1307
1308 @Test
1309 void testVarargsOverloadingResolution() {
1310
1311
1312
1313 assertEquals("Byte...", TestBean.varOverload((byte) 1, (byte) 2));
1314 assertEquals("Short...", TestBean.varOverload((short) 1, (short) 2));
1315 assertEquals("Integer...", TestBean.varOverload(1, 2));
1316 assertEquals("Long...", TestBean.varOverload(1L, 2L));
1317 assertEquals("Float...", TestBean.varOverload(1f, 2f));
1318 assertEquals("Double...", TestBean.varOverload(1d, 2d));
1319 assertEquals("Character...", TestBean.varOverload('a', 'b'));
1320 assertEquals("String...", TestBean.varOverload("a", "b"));
1321 assertEquals("Boolean...", TestBean.varOverload(true, false));
1322 assertEquals("Object...", TestBean.varOverload(1, "s"));
1323 assertEquals("Object...", TestBean.varOverload(1, true));
1324 assertEquals("Object...", TestBean.varOverload(1.1, true));
1325 assertEquals("Object...", TestBean.varOverload('c', true));
1326 assertEquals("Number...", TestBean.varOverload(1, 1.1));
1327 assertEquals("Number...", TestBean.varOverload(1, 1L));
1328 assertEquals("Number...", TestBean.varOverload(1d, 1f));
1329 assertEquals("Number...", TestBean.varOverload((short) 1, (byte) 1));
1330 assertEquals("Object...", TestBean.varOverload(1, 'c'));
1331 assertEquals("Object...", TestBean.varOverload('c', "s"));
1332 }
1333
1334 private String toString(final Class<?>[] c) {
1335 return Arrays.asList(c).toString();
1336 }
1337 }