Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limits of static method references in Java 8

I'm trying to use method references to capture method invocations and am hitting some limitations. This works fine:

<T> void capture(Function<T, ?> in) {
}

private interface Foo {
  String getBar();
} 

capture(Foo::getBar);

But if I change the signature of Foo.setBar to something like this:

private interface Foo {
  void setBar(String bar);
}

capture(Foo::setBar);

I get an error:

Cannot make a static reference to the non-static method setBar(String) from the type MyTest.Foo

It's not clear to me what the restriction is. Ideally I'd like to use method references to capture invocations on standard setter. Is there any way to do this?

like image 227
Josh Stone Avatar asked May 21 '14 21:05

Josh Stone


1 Answers

There are two problems here:

  • You're using Function, which has to return something. setBar doesn't return anything.
  • Function only takes a single input, but you've got two inputs: the Foo you'd call setBar on, and the String argument you'd pass into setBar.

If you change to use BiConsumer instead (which has a void return type and two inputs) it works fine:

static <T, U> void capture(BiConsumer<T, U> in) {
}

You can overload your capture method to have both signatures:

static <T, U> void capture(BiConsumer<T, U> in) { }
static <T> void capture(Function<T, ?> in) { }

and then use both method references:

capture(Foo::setBar);
capture(Foo::getBar);
like image 52
Jon Skeet Avatar answered Oct 03 '22 20:10

Jon Skeet