0

For example, I have a class with a method

public class SomeClass {
    public void someMethod(Object arg) {
        //some code
    }
}

And I obtained method through reflection in another class:

SomeClass instance = new SomeClass();

Method method = someClass.class.getMethod();

Is there any way to put it to a Consumer<Object> and then use with Consumer.accept(), or do I have to use something like this:

Consumer<Object> consumer = object -> method.invoke(instance, new Object())
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • 2
    What don't you like about your construct (other than using `new Object()` instead of `object` as the argument)? – RealSkeptic May 28 '18 at 12:37
  • 1
    It's mostly fine, but I'm really curious about another more elegant or alternative solution. Also, I wanted to know if it's considered bad practice. – Emil Relecto May 28 '18 at 13:42

1 Answers1

0

You can create a Consumer dynamically:

static class SomeClass {
    public void someMethod(Object arg) {
        System.out.println("test" + arg);
    }
}


static Consumer<Object> findConsumer(SomeClass instance) {
    try {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(void.class, Object.class);

        return (Consumer<Object>) LambdaMetafactory.metafactory(
                lookup,
                "accept",
                MethodType.methodType(Consumer.class, SomeClass.class),
                methodType,
                lookup.findVirtual(SomeClass.class, "someMethod", methodType),
                methodType)
                .getTarget()
                .invokeExact(instance);
    } catch (Throwable t) {
        t.printStackTrace();
        throw new RuntimeException();
    }
}

And use it:

Consumer<Object> consumer = findConsumer(new SomeClass());
    consumer.accept("hello world");
Eugene
  • 117,005
  • 15
  • 201
  • 306