Reflective method lookup, almost ten years on

Nearly ten years ago, I wrote an article exploring how to find a method on a Java class using reflection, given the class's name, the method name, and an array of arguments, whose parameter types would be most compatible with the runtime types of the actual arguments. This might be handy for, say, simple scripting languages sitting atop Java.

I sure wish someone would have told me about java.beans.Expression and java.beans.Statement when JDK 1.4 came out (2002?). Looks like it handles the exact kind of method/constructor lookup I wrote about. Plus, its ambiguity resolution is almost certainly more JLS-accurate.

The Expression/Statement facility doesn't seem to support primitive widening conversions:

import java.beans.Expression;

import org.junit.Test;
import static org.junit.Assert.*;

public class BeansExpressionTest {
    public static class Foo {
        public String bar(int i) {
            return "int";
        }

        public String bar(byte b) {
            return "byte";
        }
    }

    @Test
    public void shouldWidenPrimitives() throws Exception {
        Expression expr = new Expression(new Foo(), "bar",
            new Object[] { Short.valueOf("3") });

        assertEquals("int", expr.getValue());
    }
}

shouldWidenPrimitives() raises NoSuchMethodException. Oversight on Sun's part? Misunderstanding on my part regarding how such a call should be resolved? If I already have a handle on Foo#bar(int), the reflective call would widen a Short argument.

Written on February 25, 2010