将 Java-方法调用传递给 Scala class/method
Pass Java-method-call to Scala class/method
我必须处理这个用 Java 编写的庞大的整体代码,并且有数百个代码重复,例如:
createButtonOne() {
...
public boolean pressed() {
doSomething();
return true;
}
}
createButtonTwo() {
...
public boolean pressed() {
doAnotherThing();
return true;
}
}
除了调用的函数之外,代码字面意思是一样的,但它很烦人。当然,我可以将大部分方法外包出去,但这会比使用更好的工具正确地花费更多的时间。大概我是这么想的。
我想做的是:
ScalaButton buttonOne = new ScalaButton();
buttonOne.create("Label", Controller.doSomething());
ScalaButton buttonTwo = new ScalaButton();
buttonTwo.create("Label2", Controller.doAnotherThing());
因此我创建了 ScalaButton 如下:
class ScalaButton
{
def create(label:String, action: () => Unit): Unit =
{
val button:Button = singletonCreator.createButton(label);
button.addListener(new InputListener()
{
override def pressed(...)
{
action()
true
}
}
}
问题是我从来没有从 Java 打过这个电话,它说
found void, required scala.Function0
所以我想知道,是否有可能以这种(或另一种)方式将 java 方法调用传递给 Scala?我已经有几个月没有使用 Java 了,也从未以这种方式将它与 Scala 一起使用...
它不会编译,因为您没有将方法传递给 ScalaButton.create
,您传递的是方法调用的结果,即 void
.
如果你想从Java传递一个函数给Scala,你需要构造一个实例-在这个例子中-AbstractFunction0<BoxedUnit>
,它对应于() => Unit
.
为此,您需要:
import scala.AbstractFunction0
import scala.runtime.BoxedUnit
然后:
buttonOne.create("Label", new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
Controller.doSomething()
return BoxedUnit.UNIT;
}
});
还有一个 Function0<BoxedUnit>
,但您不想使用它 - 它不打算在 Java.
中构建
如您所见,它的使用并不十分简单。不过,如果您使用的是 Java 8,则可以稍微简化一下。
您需要像这样定义一个函数:
private static Function0<BoxedUnit> getBoxedUnitFunction0(Runnable f) {
return new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
f.run();
return BoxedUnit.UNIT;
}
};
}
别忘了import scala.Function0
- 这里没有构建,所以没关系。现在你可以像这样使用它了:
buttonOne.create("Label", getBoxedUnitFunction0(Controller::doSomething));
我必须处理这个用 Java 编写的庞大的整体代码,并且有数百个代码重复,例如:
createButtonOne() {
...
public boolean pressed() {
doSomething();
return true;
}
}
createButtonTwo() {
...
public boolean pressed() {
doAnotherThing();
return true;
}
}
除了调用的函数之外,代码字面意思是一样的,但它很烦人。当然,我可以将大部分方法外包出去,但这会比使用更好的工具正确地花费更多的时间。大概我是这么想的。
我想做的是:
ScalaButton buttonOne = new ScalaButton();
buttonOne.create("Label", Controller.doSomething());
ScalaButton buttonTwo = new ScalaButton();
buttonTwo.create("Label2", Controller.doAnotherThing());
因此我创建了 ScalaButton 如下:
class ScalaButton
{
def create(label:String, action: () => Unit): Unit =
{
val button:Button = singletonCreator.createButton(label);
button.addListener(new InputListener()
{
override def pressed(...)
{
action()
true
}
}
}
问题是我从来没有从 Java 打过这个电话,它说
found void, required scala.Function0
所以我想知道,是否有可能以这种(或另一种)方式将 java 方法调用传递给 Scala?我已经有几个月没有使用 Java 了,也从未以这种方式将它与 Scala 一起使用...
它不会编译,因为您没有将方法传递给 ScalaButton.create
,您传递的是方法调用的结果,即 void
.
如果你想从Java传递一个函数给Scala,你需要构造一个实例-在这个例子中-AbstractFunction0<BoxedUnit>
,它对应于() => Unit
.
为此,您需要:
import scala.AbstractFunction0
import scala.runtime.BoxedUnit
然后:
buttonOne.create("Label", new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
Controller.doSomething()
return BoxedUnit.UNIT;
}
});
还有一个 Function0<BoxedUnit>
,但您不想使用它 - 它不打算在 Java.
如您所见,它的使用并不十分简单。不过,如果您使用的是 Java 8,则可以稍微简化一下。
您需要像这样定义一个函数:
private static Function0<BoxedUnit> getBoxedUnitFunction0(Runnable f) {
return new AbstractFunction0<BoxedUnit>() {
@Override
public BoxedUnit apply() {
f.run();
return BoxedUnit.UNIT;
}
};
}
别忘了import scala.Function0
- 这里没有构建,所以没关系。现在你可以像这样使用它了:
buttonOne.create("Label", getBoxedUnitFunction0(Controller::doSomething));