Java Method类和Java 7的MethodHandle类都引用与方法关联的对象,但它们很少使用,当函数需要传递给另一个时,它首选使用一个匿名类来实现包含一个方法的接口。
(注意:MethodHandles应该比旧方法更快。)
为什么这些结构不经常用于将函数传递给函数?是因为它们仍然冗长吗?
代码示例:
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));
}
}
更新
在做了一些基准测试之后,我注意到MethodHandle比Reflection的方法更快,但仍然远不如常规方法调用快。也许对于方法调用,JVM可以应用一些句柄无法实现的优化。
答案 0 :(得分:3)
除了任何性能参数,传递方法或方法手柄:
此外,正如您的代码所示,使用Methods或MethodHandles并没有特别减少声明一个接近一等函数的对象所需的代码量:
// you could even use the Function types from Guava...
interface Func<In, Out> {
Out apply(In in);
}
// create a new "function" object in 5 lines of code:
Func<String, Integer> parseInt = new Func<String, Integer> {
public Integer apply(String in) {
return Integer.parseInt(in);
}
}
不可否认,它不如真正的lambda语法那么好,但是类型安全,重构的好处和易于解释使得在这五行中输入最不可能的选项。
答案 1 :(得分:0)
只在您真正需要时才使用反射。 正如你所看到的,调用thrrow Throwable意味着你没有真正好的异常处理。 其他编译时间检查也将被丢弃。
答案 2 :(得分:0)
Method类有它的位置,这比常规方法调用要慢得多。
MethodHandler是JSR 292的一部分。它针对为JVM实现动态语言的人员。您可以阅读更多相关信息here。它并不意味着要替换常规方法调用。
答案 3 :(得分:0)
MethodHandles使用反射,因此它们变慢并且不易重构。此外,Java将在其版本8中获得lambdas,这将解决Java中的第一类函数的问题,因此我认为库编写者更喜欢等待Java 8而不是使用某种解决方法。