如何使用反射来获取我可以传递的lambda的引用?

时间:2017-06-20 04:22:04

标签: java reflection lambda java-8

我可以使用反射来动态获取方法并调用它。我怎么能用lambda做同样的事情? IE就好像

class Foo{
    public static String mapper(Object o){
        return "dummy val";
    }
}

class Bar {
    public static void main(String args[]){
        String[] arr = {"a", "b", "c"};
        Lambda reflectedMapper = ReflectionUtils.getLambda("Foo.mapper");//How do I actually write this line?
        List<String> mapped = arr.stream().map(reflectedMapper).collect(Collectors.toList();
    }
}

2 个答案:

答案 0 :(得分:3)

如果我理解正确,例如:

static class Test {
    public static boolean transform(String s) {
        return s.toUpperCase().equals("SOME");
    }
}

您可以获得您要找的Function,例如:

MethodType methodType = MethodType.methodType(boolean.class, String.class);
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodHandle handle = lookup.findStatic(Test.class, "transform", methodType);
    Function<String, Boolean> f = (Function<String, Boolean>) LambdaMetafactory.metafactory(
            lookup, "apply",
            MethodType.methodType(Function.class),
            methodType.generic(),
            handle,
            methodType)
            .getTarget().invokeExact();

另请注意,此同一方法也符合Predicate的条件;因为它的签名是String, boolean,可以这样使用:

  MethodType predicateMT = MethodType.methodType(boolean.class, Object.class);
    MethodType stringPredicateMT = MethodType.methodType(boolean.class, String.class);

    MethodType methodType = MethodType.methodType(boolean.class, String.class);

    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodHandle handle = lookup.findStatic(Test.class, "transform", methodType);
    Predicate<String> p = (Predicate<String>) LambdaMetafactory.metafactory(
            lookup, "test",
            MethodType.methodType(Predicate.class),
            predicateMT,
            handle,
            stringPredicateMT)
            .getTarget().invokeExact();


 System.out.println(p.test("Some"));

答案 1 :(得分:-1)

你可以这样做。

static Function<Object, String> getLambda(Class<?> clazz, String methodName) {
    Method m;
    try {
        m = clazz.getMethod(methodName, Object.class);
    } catch (NoSuchMethodException | SecurityException e) {
        throw new RuntimeException(e);
    }
    return arg -> {
        try {
            return (String) m.invoke(null, arg);
        } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
            throw new RuntimeException(e);
        }
    };
}

List<String> list = Arrays.asList("a", "b", "c");
List<String> mapped = list.stream()
    .map(getLambda(Foo.class, "mapper"))
    .collect(Collectors.toList());
System.out.println(mapped);