Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 605
Mustafa Avatar asked Aug 10 '15 19:08

Mustafa


People also ask

Which referencing is allowed in Java 8?

Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

What is method reference and constructor references in Java 8?

A method reference requires a target type similar to lambda expressions. But instead of providing an implementation of a method, they refer to a method of an existing class or object while a constructor reference provides a different name to different constructors within a class.

Can be replaced with method reference lambda?

If you are using a lambda expression as an anonymous function but not doing anything with the argument passed, you can replace lambda expression with method reference. In the first two cases, the method reference is equivalent to lambda expression that supplies the parameters of the method e.g. System.


1 Answers

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.

like image 147
Alexey Romanov Avatar answered Oct 08 '22 18:10

Alexey Romanov