Finding most specific overloaded method using MethodHandle

前端 未结 5 437
旧时难觅i
旧时难觅i 2020-12-14 01:50

Suppose I have three methods inside a given type (class/interface):

public void foo(Integer integer);
public void foo(Number number);
public void foo(Object          


        
5条回答
  •  无人及你
    2020-12-14 02:25

    Given the constraints that: a) the type of the parameter is only known at runtime, and b) there is only one parameter, a simple solution can be just walking up the class hierarchy and scanning the implemented interfaces like in the following example.

    public class FindBestMethodMatch {
    
        public Method bestMatch(Object obj) throws SecurityException, NoSuchMethodException {
            Class superClss = obj.getClass();
            // First look for an exact match or a match in a superclass
            while(!superClss.getName().equals("java.lang.Object")) {
                try {
                    return getClass().getMethod("foo", superClss);          
                } catch (NoSuchMethodException e) {
                    superClss = superClss.getSuperclass();
                }
            }
            // Next look for a match in an implemented interface
            for (Class intrface : obj.getClass().getInterfaces()) {
                try {
                    return getClass().getMethod("foo", intrface);
                } catch (NoSuchMethodException e) { }           
            }
            // Last pick the method receiving Object as parameter if exists
            try {
                return getClass().getMethod("foo", Object.class);
            } catch (NoSuchMethodException e) { }
    
            throw new NoSuchMethodException("Method not found");
        }
    
        // Candidate methods
    
        public void foo(Map map) { System.out.println("executed Map"); } 
    
        public void foo(Integer integer) { System.out.println("executed Integer"); } 
    
        public void foo(BigDecimal number) { System.out.println("executed BigDecimal"); }
    
        public void foo(Number number) { System.out.println("executed Number"); }
    
        public void foo(Object object) { System.out.println("executed Object"); }
    
        // Test if it works
        public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
            FindBestMethodMatch t = new FindBestMethodMatch();
            Object param = new Long(0);
            Method m = t.bestMatch(param);
            System.out.println("matched " + m.getParameterTypes()[0].getName());
            m.invoke(t, param);
            param = new HashMap();
            m = t.bestMatch(param);
            m.invoke(t, param);
            System.out.println("matched " + m.getParameterTypes()[0].getName());
        }
    
    }
    

提交回复
热议问题