Java Method Class and Java 7’s MethodHandle Class both refer to objects that are associated to methods, but still they are rarely used and when a function needs to be passed to another, it is preferred to use an anonymous class that implements an interface that contains one method.
(Note: MethodHandles are supposed to be faster than the old Methods.)
Why aren’t these constructs used more often to pass functions to functions? Is it because they are still verbose?
Code example:
public final class HigherOrder {
public static final List<?> map(final List<?> list, final MethodHandle mh) throws Throwable {
if (list == null) return null;
List<Object> ret = new ArrayList<>(list.size());
for (Object element : list) {
ret.add(mh.invoke(element));
}
return ret;
}
public static final Object reduce(final List<?> list, final MethodHandle mh) throws Throwable {
if (list == null) return null;
Object tmp = list.get(0);
for (int i = 1; i < list.size(); i++) {
tmp = mh.invoke(tmp, list.get(i));
}
return tmp;
}
public static final Integer doubleNumber(final Integer number) {
return number * 2;
}
public static final Integer sum(final Integer number1, final Integer number2) {
return number1 + number2;
}
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle doubleNumber = lookup.unreflect(HigherOrder.class.getMethod("doubleNumber", Integer.class));
MethodHandle sum = lookup.findStatic(HigherOrder.class, "sum", MethodType.methodType(Integer.class, Integer.class, Integer.class));
List<?> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(list);
list = map(list, doubleNumber);
System.out.println(list);
System.out.println(reduce(list, sum));
}
}
UPDATE
After doing some benchmarking, I noticed that MethodHandle is faster than Reflection’s method, but still nowhere near as fast as a regular method call. Maybe for the method call the JVM can apply some optimizations that are not possible with the handles.
Aside from any performance arguments, passing around Methods or MethodHandles:
Also, as your code demonstrates, using Methods or MethodHandles doesn’t particularly cut down on the amount of code required to declare an object approximating a first-class function:
Admittedly it’s not as nice as a real lambda syntax, but the type-safety, refactoring benefits and ease of explanation make typing out those five lines the least-worst option much of the time.