循环内创建多个Runnable的替代方案(规避final变量)
解决循环内创建Runnable引用循环变量的问题
方案1:提取为独立方法传递参数
把创建Runnable的逻辑抽成单独方法,每次循环调用时传入当前的i值。方法参数在lambda中天然属于有效final变量,无需额外声明临时变量。
// 循环创建Ctrl+1至Ctrl+9的快捷键 for (int i = 1; i <= 9; i++) { KeyCombination combo = new KeyCodeCombination(KeyCode.getKeyCode(String.valueOf(i)), KeyCombination.CONTROL_DOWN); getScene().getAccelerators().put(combo, createCopyAction(i)); } // 封装Runnable创建逻辑的独立方法 private Runnable createCopyAction(int index) { return () -> { checkDestinationValidity(index); copyImage(index); }; }
方案2:使用IntStream迭代替代普通for循环
用IntStream.rangeClosed生成1到9的整数流,forEach中的每个元素都是独立的有效final变量,直接引用不会触发编译错误。
IntStream.rangeClosed(1, 9).forEach(i -> { KeyCombination combo = new KeyCodeCombination(KeyCode.getKeyCode(String.valueOf(i)), KeyCombination.CONTROL_DOWN); getScene().getAccelerators().put(combo, () -> { checkDestinationValidity(i); copyImage(i); }); });
方案3:自定义Runnable实现类
创建实现Runnable的内部类,在构造时传入循环变量i作为成员变量,每个实例持有独立的索引值,彻底规避lambda捕获变量的限制。
// 自定义Runnable实现类 private class CopyImageRunnable implements Runnable { private final int index; public CopyImageRunnable(int index) { this.index = index; } @Override public void run() { checkDestinationValidity(index); copyImage(index); } } // 循环创建快捷键与Runnable实例 for (int i = 1; i <= 9; i++) { KeyCombination combo = new KeyCodeCombination(KeyCode.getKeyCode(String.valueOf(i)), KeyCombination.CONTROL_DOWN); getScene().getAccelerators().put(combo, new CopyImageRunnable(i)); }
内容的提问来源于stack exchange,提问作者Juraon
相关产品推荐
相关产品推荐

