Just a theoretical question, I currently have no practical use.
Assuming that some of my API accepts a link to a function as an argument, and I would like to either pass it directly from the code through the syntax "::", or collect the corresponding functions through reflection, store on some map and call it conditionally.
Can I programmatically convert methodto Consumer<String>?
Map<String, Consumer<String>> consumers = new HashMap<>();
consumers.put("println", System.out::println);
Method method = PrintStream.class.getMethod("println", String.class);
consumers.put("println", makeFunctionReference(method));
...
myapi.feedInto(consumers.get(someInput.getConsumerId()));
Update
Although not satisfied with the solutions in the current answers, but after getting a hint about LambdaMetaFactory, I tried to compile this code
public class TestImpl {
public static void FnForString(String arg) {}
}
public class Test {
void test() {
List<String> strings = new ArrayList<>();
Consumer<String> stringConsumer = TestImpl::FnForString;
strings.stream().forEach(stringConsumer);
strings.stream().forEach(TestImpl::FnForString);
stringConsumer.accept("test");
}
}
and after submitting only the test class to CFR decompiler I go back:
public class Test {
void test() {
ArrayList strings = new ArrayList();
Consumer<String> stringConsumer =
(Consumer<String>)LambdaMetafactory.metafactory(
null, null, null,
(Ljava/lang/Object;)V,
FnForString(java.lang.String),
(Ljava/lang/String;)V)();
strings.stream().forEach(stringConsumer);
strings.stream().forEach(
(Consumer<String>)LambdaMetafactory.metafactory(
null, null, null,
(Ljava/lang/Object;)V,
FnForString(java.lang.String ),
(Ljava/lang/String;)V)());
stringConsumer.accept("test");
}
}
From this, I see that:
- It is somehow possible to do in the style of "1-liner"
- ,
(Ljava/lang/Object;)V ( ) . MethodType metafactory(). - "/" -, , , . - (offtop) - - , .
... Test TestImpl, CFR , .