Search code examples
javascalajava-8javafx-8

Is it possible to use a Java 8 style method references in Scala?


I'm developing a JavaFX8 application in Scala but I couldn't figure out how to pass a method reference to an event handler. To clarify, I'm not using ScalaFX library but build my application directly on top of JavaFX.

Here's the related code snippet.

InputController.java (I wrote this test class in Java to isolate the issue to consume a method reference only)

public class InputController {
    public void handleFileSelection(ActionEvent actionEvent){
        //event handling code
    }

    public InputController() {
        //init controller
    }
}

This works (Java)

InputController inputController = new InputController();
fileButton.setOnAction(inputController::handleFileSelection);

This doesn't work (Scala)

val inputController = new InputController
fileButton.setOnAction(inputController::handleFileSelection)

Here's the error message from the compiler (Scala 2.11.6).

Error:(125, 45) missing arguments for method handleFileSelection in class Main;
follow this method with '_' if you want to treat it as a partially applied function
    fileButton.setOnAction(inputController::handleFileSelection)
                                            ^

If I use Scala 2.12.0-M2 instead, I get a different error message.

Error:(125, 45) missing argument list for method handleFileSelection in class Main
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `handleFileSelection _` or `handleFileSelection(_)` instead of `handleFileSelection`.
    fileButton.setOnAction(inputController::handleFileSelection)
                                            ^

Is there a native way which Scala can leverage method references introduced in Java 8? I'm aware of the implicit conversions approach to use a lambda expression but I want to know if there is a way to use a method reference similar to Java 8 without needing to use the lambda decleration.


Solution

  • inputController::handleFileSelection is Java syntax, which isn't supported or needed in Scala because it already had a short syntax for lambdas like this: inputController.handleFileSelection _ or inputController.handleFileSelection(_) (inputController.handleFileSelection can also work, depending on the context).

    However, in Java you can use lambdas and method references when any SAM (single abstract method) interface is expected, and EventHandler is just such an interface. In Scala before version 2.11 this isn't allowed at all, in 2.11 there is experimental support for using lambdas with SAM interfaces, which has to be enabled using -Xexperimental scalac flag, and starting from 2.12 it is fully supported and doesn't need to be enabled.