6

Suppose I have some functional interface like Function and some methods of different classes for which I can take method references, for example:

class A {
   public int getPrimitive() { return 0; }
   public Integer getBoxed() { return 0; }
   public static int getStaticPrimitive(A a) { return 1; }
}

Function<A, Integer> primitive = A::getPrimitive;
Function<A, Integer> boxed = A::getBoxed;
Function<A, Integer> staticPrimitive = A::getStaticPrimitive;

How I can grab all possible method references converted to instances of Function interface from class A via reflection?

Update:

The question isn't a duplicate of any mentioned in comments so far, but thanks to the both questions mentioned by Holger's in his comment I've managed to do what I've needed:

    class Test {
    public static void main(String[] args) throws Throwable {
        HashMap<String, Function<A, Integer>> map = new HashMap<>();

        Collection<MethodType> supportedTypes = Arrays.asList(
                MethodType.methodType(int.class, A.class),
                MethodType.methodType(Integer.class, A.class)
        );

        MethodType inT = MethodType.methodType(Function.class);
        MethodHandles.Lookup l = MethodHandles.lookup();
        for (Method m : A.class.getDeclaredMethods()) {
            MethodHandle mh = l.unreflect(m);
            if (!supportedTypes.contains(mh.type())) {
                continue;
            }
            map.put(m.getName(), (Function<A, Integer>) LambdaMetafactory.metafactory(
                    l, "apply", inT, mh.type().generic(), mh, mh.type()).getTarget().invoke());
        }

        A a = new A();
        map.forEach((name, op) -> System.out.println(name + "(a) => " + op.apply(a)));
    }

    static class A {
        public int getPrimitive() {
            return 0;
        }

        public Integer getBoxed() {
            return 1;
        }

        public static Integer getStaticBoxed(A a) {
            return 2;
        }

        public static int getStaticPrimitive(A a) {
            return 3;
        }
    }
}
Community
  • 1
  • 1
okutane
  • 13,754
  • 10
  • 59
  • 67
  • Do you mean https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html? – Hannes Apr 17 '15 at 16:18
  • Write a `Function` implementation that invokes the methods reflectively. What more do you want? You can't create a function reference at runtime - this requires compiler magic. – Boris the Spider Apr 17 '15 at 16:18
  • 1
    Similar to http://stackoverflow.com/questions/19845213/how-to-get-the-methodinfo-of-a-java-8-method-reference ? – BretC Apr 17 '15 at 16:19
  • 1
    @BoristheSpider well, you can still use ASM for instance and create a `CallSite` which you pass to `invokedynamic`, but yeah, that's black arts – fge Apr 17 '15 at 16:22
  • 4
    I don’t get the question. These method references *are* already instances of `Function`. Maybe you want [Convert MethodHandle to method reference](http://stackoverflow.com/q/27417634/2711488) or [… get Method Reference for all methods in a class](http://stackoverflow.com/q/29347434/2711488)? – Holger Apr 17 '15 at 16:30

0 Answers0