1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
17
17
package org .springframework .util ;
18
18
19
19
import java .beans .Introspector ;
20
-
21
20
import java .lang .reflect .Array ;
22
21
import java .lang .reflect .Constructor ;
23
22
import java .lang .reflect .Method ;
24
23
import java .lang .reflect .Modifier ;
25
24
import java .lang .reflect .Proxy ;
26
-
27
25
import java .security .AccessControlException ;
28
-
29
26
import java .util .Arrays ;
30
27
import java .util .Collection ;
31
28
import java .util .Collections ;
@@ -578,7 +575,7 @@ public static boolean matchesTypeName(Class<?> clazz, String typeName) {
578
575
/**
579
576
* Determine whether the given class has a public constructor with the given signature.
580
577
* <p>Essentially translates {@code NoSuchMethodException} to "false".
581
- * @param clazz the clazz to analyze
578
+ * @param clazz the clazz to analyze
582
579
* @param paramTypes the parameter types of the method
583
580
* @return whether the class has a corresponding constructor
584
581
* @see Class#getMethod
@@ -591,7 +588,7 @@ public static boolean hasConstructor(Class<?> clazz, Class<?>... paramTypes) {
591
588
* Determine whether the given class has a public constructor with the given signature,
592
589
* and return it if available (else return {@code null}).
593
590
* <p>Essentially translates {@code NoSuchMethodException} to {@code null}.
594
- * @param clazz the clazz to analyze
591
+ * @param clazz the clazz to analyze
595
592
* @param paramTypes the parameter types of the method
596
593
* @return the constructor, or {@code null} if not found
597
594
* @see Class#getConstructor
@@ -607,9 +604,9 @@ public static <T> Constructor<T> getConstructorIfAvailable(Class<T> clazz, Class
607
604
}
608
605
609
606
/**
610
- * Determine whether the given class has a method with the given signature.
607
+ * Determine whether the given class has a public method with the given signature.
611
608
* <p>Essentially translates {@code NoSuchMethodException} to "false".
612
- * @param clazz the clazz to analyze
609
+ * @param clazz the clazz to analyze
613
610
* @param methodName the name of the method
614
611
* @param paramTypes the parameter types of the method
615
612
* @return whether the class has a corresponding method
@@ -620,44 +617,85 @@ public static boolean hasMethod(Class<?> clazz, String methodName, Class<?>... p
620
617
}
621
618
622
619
/**
623
- * Determine whether the given class has a method with the given signature,
620
+ * Determine whether the given class has a public method with the given signature,
624
621
* and return it if available (else throws an {@code IllegalStateException}).
622
+ * <p>In case of any signature specified, only returns the method if there is a
623
+ * unique candidate, i.e. a single public method with the specified name.
625
624
* <p>Essentially translates {@code NoSuchMethodException} to {@code IllegalStateException}.
626
- * @param clazz the clazz to analyze
625
+ * @param clazz the clazz to analyze
627
626
* @param methodName the name of the method
628
627
* @param paramTypes the parameter types of the method
628
+ * (may be {@code null} to indicate any signature)
629
629
* @return the method (never {@code null})
630
630
* @throws IllegalStateException if the method has not been found
631
631
* @see Class#getMethod
632
632
*/
633
633
public static Method getMethod (Class <?> clazz , String methodName , Class <?>... paramTypes ) {
634
634
Assert .notNull (clazz , "Class must not be null" );
635
635
Assert .notNull (methodName , "Method name must not be null" );
636
- try {
637
- return clazz .getMethod (methodName , paramTypes );
636
+ if (paramTypes != null ) {
637
+ try {
638
+ return clazz .getMethod (methodName , paramTypes );
639
+ }
640
+ catch (NoSuchMethodException ex ) {
641
+ throw new IllegalStateException ("Expected method not found: " + ex );
642
+ }
638
643
}
639
- catch (NoSuchMethodException ex ) {
640
- throw new IllegalStateException ("Expected method not found: " + ex );
644
+ else {
645
+ Set <Method > candidates = new HashSet <Method >(1 );
646
+ Method [] methods = clazz .getMethods ();
647
+ for (Method method : methods ) {
648
+ if (methodName .equals (method .getName ())) {
649
+ candidates .add (method );
650
+ }
651
+ }
652
+ if (candidates .size () == 1 ) {
653
+ return candidates .iterator ().next ();
654
+ }
655
+ else if (candidates .isEmpty ()) {
656
+ throw new IllegalStateException ("Expected method not found: " + clazz + "." + methodName );
657
+ }
658
+ else {
659
+ throw new IllegalStateException ("No unique method found: " + clazz + "." + methodName );
660
+ }
641
661
}
642
662
}
643
663
644
664
/**
645
- * Determine whether the given class has a method with the given signature,
665
+ * Determine whether the given class has a public method with the given signature,
646
666
* and return it if available (else return {@code null}).
667
+ * <p>In case of any signature specified, only returns the method if there is a
668
+ * unique candidate, i.e. a single public method with the specified name.
647
669
* <p>Essentially translates {@code NoSuchMethodException} to {@code null}.
648
- * @param clazz the clazz to analyze
670
+ * @param clazz the clazz to analyze
649
671
* @param methodName the name of the method
650
672
* @param paramTypes the parameter types of the method
673
+ * (may be {@code null} to indicate any signature)
651
674
* @return the method, or {@code null} if not found
652
675
* @see Class#getMethod
653
676
*/
654
677
public static Method getMethodIfAvailable (Class <?> clazz , String methodName , Class <?>... paramTypes ) {
655
678
Assert .notNull (clazz , "Class must not be null" );
656
679
Assert .notNull (methodName , "Method name must not be null" );
657
- try {
658
- return clazz .getMethod (methodName , paramTypes );
680
+ if (paramTypes != null ) {
681
+ try {
682
+ return clazz .getMethod (methodName , paramTypes );
683
+ }
684
+ catch (NoSuchMethodException ex ) {
685
+ return null ;
686
+ }
659
687
}
660
- catch (NoSuchMethodException ex ) {
688
+ else {
689
+ Set <Method > candidates = new HashSet <Method >(1 );
690
+ Method [] methods = clazz .getMethods ();
691
+ for (Method method : methods ) {
692
+ if (methodName .equals (method .getName ())) {
693
+ candidates .add (method );
694
+ }
695
+ }
696
+ if (candidates .size () == 1 ) {
697
+ return candidates .iterator ().next ();
698
+ }
661
699
return null ;
662
700
}
663
701
}
@@ -1025,7 +1063,7 @@ public static Class<?>[] toClassArray(Collection<Class<?>> collection) {
1025
1063
* @param instance the instance to analyze for interfaces
1026
1064
* @return all interfaces that the given instance implements as array
1027
1065
*/
1028
- public static Class [] getAllInterfaces (Object instance ) {
1066
+ public static Class <?> [] getAllInterfaces (Object instance ) {
1029
1067
Assert .notNull (instance , "Instance must not be null" );
1030
1068
return getAllInterfacesForClass (instance .getClass ());
1031
1069
}
0 commit comments