Functional interface confusion

Stephen Colebourne scolebourne at joda.org
Sat Jul 6 14:39:40 PDT 2013


I tried to create this interface today, and the compiler complained:

@FunctionalInterface
public interface TemporalAdjuster {
    <T extends Temporal> T adjustInto(T temporal);
}

static TemporalAdjuster firstDayOfMonth() {
  return (temporal) -> temporal.with(DAY_OF_MONTH, 1);
}

java: incompatible types: invalid functional descriptor for lambda expression
    method <T>(T)T in interface java.time.temporal.TemporalAdjuster is generic

The same error was seen with this:
static <T extends Temporal> TemporalAdjuster firstDayOfMonth() {
  return (T temporal) -> (T) temporal.with(DAY_OF_MONTH, 1);
}

I must admit that I wasn't expecting this, as nothing in the
documentation of @FunctionalInterface or other recent discussions that
I have seen indicated to me that there is a limitation on lambdas and
method-based generics. (FYI, method-based generics are correct here.
Generifying the interface TemporalAdjuster would not represent the
same logical thing in the codebase. The only constraint is on the
method.)

By contrast, this seems to work fine:

@FunctionalInterface
public interface TemporalQuery<R> {
    R queryFrom(TemporalAccessor temporal);
}
static final TemporalQuery<ZoneId> ZONE_ID = (temporal) -> {
  return temporal.query(ZONE_ID);
};


Is the compiler wrong? Is the spec of FunctionalInterface incomplete
(perhaps deliberately)?
(compiler I'm using is old and on the
http://hg.openjdk.java.net/threeten/threeten/jdk branch)

I think I understand why the first example cannot be a lambda, as
there is no way to grab the <T> in the lambda body, but I'd like a
proper explanation! It definitely feels like an awkward edge case, and
I suspect I'll be forced back to the ungenerified version.

thanks
Stephen


More information about the lambda-dev mailing list