Finding most specific overloaded method using MethodHandle

前端 未结 5 420
旧时难觅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:22

    I couldn't find a way to do this with MethodHandles, but there is an interesting java.beans.Statement that implements finding the JLS' most specific method according to the Javadocs:

    The execute method finds a method whose name is the same as the methodName property, and invokes the method on the target. When the target's class defines many methods with the given name the implementation should choose the most specific method using the algorithm specified in the Java Language Specification (15.11).

    To retrieve the Method itself, we can do so using reflection. Here's a working example:

    import java.beans.Statement;
    import java.lang.reflect.Method;
    
    public class ExecuteMostSpecificExample {
        public static void main(String[] args) throws Exception {
            ExecuteMostSpecificExample e = new ExecuteMostSpecificExample();
            e.process();
        }
    
        public void process() throws Exception {
            Object object = getLong();
            Statement s = new Statement(this, "foo", new Object[] { object });
    
            Method findMethod = s.getClass().getDeclaredMethod("getMethod", Class.class,
                                                               String.class, Class[].class);
            findMethod.setAccessible(true);
            Method mostSpecificMethod = (Method) findMethod.invoke(null, this.getClass(),
                                                  "foo", new Class[] { object.getClass() });
    
            mostSpecificMethod.invoke(this, object);
        }
    
        private Object getLong() {
            return new Long(3L);
        }
    
        public void foo(Integer integer) {
            System.out.println("Integer");
        }
    
        public void foo(Number number) {
            System.out.println("Number");
        }
    
        public void foo(Object object) {
            System.out.println("Object");
    
        }
    }
    

提交回复
热议问题