
private void myTest(boolean isNeeded) { //业务需求:遍历一个 list 的过程中,如果 isNeeded 为 true,则为 neededList 插入数据 // ↓为编译器错误, // ArrayList<Integer> neededList = null; // if (isNeeded) neededList = new ArrayList<&g;(); // ↓通过检查 ArrayList<Integer> neededList = new ArrayList<>(); ArrayList<String> list = new ArrayList<>(); //...处理其他业务 list.forEach(element -> { //...处理其他业务 if (isNeeded) neededList.add(1); }); } 为啥他就感知不到 false 的情况不会执行呢...
1 wwqgtxx 2020-05-24 07:06:20 +08:00 via iPhone java 中 lamdba 表达式捕获的变量需要隐式的为 final 类型的吧 |
2 fewok 2020-05-24 09:02:08 +08:00 list 插条数据呗,你这例子,list 是空数组,怎么可能会执行 foreach 里的内容呢? |
3 w292614191 2020-05-24 09:57:46 +08:00 哈哈哈哈哈哈哈哈,是你故意这样写的,还是我太菜了。 |
4 chendy 2020-05-24 10:46:57 +08:00 Variable used in lambda expression should be final or effectively final |
5 Aresxue 2020-05-24 10:54:30 +08:00 lambda 里面的变量需要是 final 的, 使用的变量被隐式转为了 final, 编译器报错不是因为不会推断,而是你在给一个 final 变量重新赋值,手动加上 final 你就会知道真正的报错是在 neededList = new ArrayList<>(); 这里 |
6 Liyiw 2020-05-24 11:43:54 +08:00 不是太懂这个描述。。 |
9 yousabuk 2020-05-24 13:20:59 +08:00 via iPhone jvm 编译器被谁蠢哭了呢 |
10 EscYezi 2020-05-24 13:33:51 +08:00 via iPhone @Liyiw needList 初始值是 null,接着 if 里面又给 needList 赋值了新的对象;像#5 所说的,needList 被编译器增加了 final,这样做是在给 final 变量重新赋值 |
13 HeapOverflow 2020-05-24 17:30:55 +08:00 via iPhone 是 JVM 被你蠢哭了 |
14 Kaiv2 2020-05-24 23:19:57 +08:00 via Android 明白你的意思了,个人理解: lamdba 表达式可以存在变量里,使用外部可变引用可能会增加复杂性。这里的例子如果在 forEach 中将 neededList 指向新的对象了,外部变量是否也修改呢? 如果只是使用forEach 遍历建议修改为 for 迭代器模式,可以解决这个问题。 |