当我编写这段代码时,我得到一个编译时错误,上面写着: 'lambdas中的变量必须是最终的或有效的最终'.
现在,我得到这个从行中删除i:
futureLists.add(executorService.submit(() - >"Hello world"+ i));
解决了这个问题.
但我想知道为什么存在这样的要求?
根据JLS,它说的是:
使用但未在lambda表达式中声明的任何局部变量,形式参数或异常参数必须声明为final或有效final,否则在尝试使用时会发生编译时错误.
但它没有说明,为什么存在这样的要求.但是为什么Java工程师对lambdas强制执行这样的要求呢?
public class test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<String>> futureLists = new ArrayList<>();
for (int i = 0; i < 20; i++) {
futureLists.add(executorService.submit( () -> "Hello world" + i));
}
for (Future<String> itr:futureLists) {
System.out.println(itr.get());
}
}
}
Run Code Online (Sandbox Code Playgroud) 我参加了一次面试,并被要求为以下要求设计一个课程。假设我有一个 A 类,它可以有任意数量的子类,即子类。类 A 有一个名为 doSomething() 的方法,它是同步的。要求是:
A 的所有子类都必须覆盖 doSomething()方法。
所有子类的重写 doSomething() 方法本质上必须是线程安全的。
所有子类都必须为它们的 doSomething() 方法实现提供自己的逻辑。
A 类的构造函数由我(设计者)决定如何实现。
设计者无法控制将创建多少子类或如何创建它们,即设计者只能为超类编写代码。
我建议将类抽象化,并将 doSomething() 方法抽象化。这意味着扩展我的类的类必须提供自己的 doSomething() 方法。
但是,我无法回答在我的类 A 中究竟什么可以确保我的子类的线程安全,而这也仅适用于 doSomething() 方法。
不过他给出了一个提示,他说诀窍是在 A 类的构造函数中完成。
有任何想法吗?