是否可以在Scala中使用Java 8样式方法引用?

时间:2015-08-10 19:23:44

标签: java scala java-8 javafx-8

我正在Scala中开发JavaFX8应用程序,但我无法弄清楚如何将方法引用传递给事件处理程序。为了澄清,我没有使用ScalaFX库,而是直接在JavaFX上构建我的应用程序。

以下是相关的代码段。

InputController.java (我在Java中编写了这个测试类,以隔离问题只使用方法引用)

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

    public InputController() {
        //init controller
    }
}

这适用于(Java)

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

这不起作用(Scala)

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

以下是编译器的错误消息(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)
                                            ^

如果我使用Scala 2.12.0-M2,我会收到不同的错误消息。

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)
                                            ^

是否存在Scala可以利用Java 8中引入的方法引用的本机方式?我知道使用lambda表达式的隐式转换方法,但我想知道是否有办法使用类似于Java 8的方法引用而不需要使用lambda decleration。

3 个答案:

答案 0 :(得分:14)

inputController::handleFileSelection是Java语法,Scala不支持或不需要它,因为它已经有一个简短的lambdas语法,如:inputController.handleFileSelection _inputController.handleFileSelection(_)inputController.handleFileSelection也可以工作,具体取决于具体情况。)

但是,在Java中,当需要任何SAM(单个抽象方法)接口时,您可以使用lambdas和方法引用,而EventHandler就是这样的接口。在版本2.11之前的Scala中,这是完全不允许的,在2.11中有使用lambdas和SAM接口的实验性支持,必须使用-Xexperimental scalac标志启用,并且从2.12开始它完全支持并且不支持不需要启用。

答案 1 :(得分:3)

您应该传递应用 select * from podConfigKey_Tab PCK WHERE CASE WHEN (PCK.Keyid = 'TLMAPIConfigMgr.UseDB' and PCK.DEFAULTKEYIDVALUE = 'FALSE') THEN PCK.Keyid = 'TLMAPIConfigMgr.UseDB' ELSE PCK.Keyid != 'TLMAPIConfigMgr.UseDB' END; 类型的一个参数的函数:

ActionEvent

答案 2 :(得分:0)

如果您希望方法引用也将类实例作为参数,例如Java中的String::length,则可以执行与(_:String).length等效的(s:String) => s.length()

它们的类型在Java Function<String, Integer>中,在Scala中也是如此,String => Int