java - 如何在不使用 Lambda 的情况下编写此代码并且仍然可以正常工作?
问题描述
我正在尝试在不使用 lambda 的情况下将此代码转换为工作,以便我可以更好地理解它,但我一点运气都没有。如何用ActionEvent
类似于按钮的 s 来编写它?
enemyBoard = new Board(true, event -> {
if (!running)
return;
Cell cell = (Cell) event.getSource();
if (cell.wasShot)
return;
enemyTurn = !cell.shoot();
if (enemyBoard.ships == 0) {
System.out.println("YOU WIN");
System.exit(0);
}
if (enemyTurn)
enemyMove();
});
这是Board
构造函数:
public Board(boolean enemy, EventHandler<? super MouseEvent> handler) {
this.enemy = enemy;
for (int y = 0; y < 10; y++) {
HBox row = new HBox();
for (int x = 0; x < 10; x++) {
Cell c = new Cell(x, y, this);
c.setOnMouseClicked(handler);
row.getChildren().add(c);
}
rows.getChildren().add(row);
}
getChildren().add(rows);
}
代码属于战舰游戏,这里是游戏代码的链接:https ://github.com/AlmasB/Battleship/tree/master/src/com/almasb/battleship 。
解决方案
enemyBoard = new Board(true, event -> { ... });
lambda 是实现功能接口的一种简写方式,它是一个interface
带有单个(非default
)方法的方法。没有 lambda 的等效代码是:
enemyBoard = new Board(true, new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
...
}
});
就是这样。它只是用于实例化匿名并实现其单一方法的语法糖† 。EventHandler
handle()
我省略了方法主体,因为两者都相同。
如果这看起来仍然很奇怪,那么写作new ClassOrInterface() { ... }
本身也是一种语法糖。我们可以应用另一轮去糖并显式写出匿名类:
class EventHandler$1 implements EventHandler<MouseEvent> {
public void handle(MouseEvent event) {
...
}
}
enemyBoard = new Board(true, new EventHandler$1());
请注意,这EventHandler$1
是一个自动生成的类名,保证不会与任何其他真实类发生冲突。编译器使用一个$
在最终用户代码中不合法的字符来命名类,使其不会发生冲突。如果您曾经在堆栈跟踪中看到带有美元符号的类名,那么这就是它们的来源:匿名类。
†正如@user 指出的那样,它实际上更复杂。Lambdas 并不总是对匿名类脱糖。通常编译器可以做一些更有效的事情。但从概念上讲,将它们视为匿名类是一种在心理上翻译它们的好方法。
推荐阅读
- oracle - 我们可以在存储过程中调用存储过程吗?
- oracle - 获取 SDO.GEOMETRY 折线的中点
- c# - 如何使用 UseExceptionHandler Startup mvc core 获取 baseurl
- html - 子帧错误详细信息为什么我看不到某些帧?
- python - 没有名为“django.contrib.staticfiles.templatetags”的模块
- image - Imagemagick在转换为PNG时忽略应用于SVG中文本元素的textlength样式
- c++ - SkParagraph 不塑造或呈现文本
- svm - 如何在支持向量机中使用关于 svc.predict 的分类函数?
- ios - 如何在没有情节提要的情况下更改视图控制器
- visual-studio-2017 - 在寄存器中添加自定义 SQL 列