SAM/Functional Interfaces and interoperability with Java

I’m porting a library of mine to Kotlin though I would still keep it usable in Java (btw. I’m a Kotlin novice).
So here’s an Java example where I’m stuck (I could rewrite some code but I obviously would prefer a nice solution):

public class MPredicate<T> {

  boolean test(to: T) throws Exception;

  default MPredicate<T> negate() {
      return $ -> !test($);
  }

}

Obviously this contains two functions though one is a default one. In Java I can simply use this functional interface like this:

public class Dodo {
  private static MPredicate<String> PREDICATE = $ -> "dodo".equals($);
}

However if I port MPredicate to Kotlin this won’t fly as the lambda expression doesn’t allow to be instantiated due to the additional negate method (SAM conversion doc explicitly states that only one function is allowed).

Is there a way to solve this nicely (extracting those additional methods is possible but I’d like to keep these default methods around)?

Thanks in advance.

Where did you read this? Docs say something quite opposite:

The functional interface can have several non-abstract members but only one abstract member.

I guess the missing bit in your interface definition is fun keyword. This is required for SAM conversions to work.

1 Like

Thanks.
I read that in an article which wasn’t as clear as the documentation on your link. However this clearly indicated that I did something wrong as I wasn’t missing the fun keyword.
Investigating the class with javap I figured that the generated class had two abstract methods which lead me to the missing ingredient: The compiler option -Xjvm-default=all.

Problem solved.