我有这样的平安守则:
private final static Thread mainThread = Thread.currentThread();
private final static ScheduledFuture<?> consumeSchedule;
static{
Runnable consumeMessages = () -> {
//...Some code...
//stop the printSchedule
if(!mainThread.isAlive()){
consumeSchedule.cancel(false); //Variable might not have been initialized
}
};
//this will execute until the main thread will stop.
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
consumeSchedule = executor.scheduleAtFixedRate(consumeMessages, 0, printRateMS, TimeUnit.MILLISECONDS);
}
如何避免“变量可能未初始化”错误,因为很明显,cancel
将在printSchedule
初始化后调用。
或者如何在主线程终止时停止consumeSchedule?
1条答案
按热度按时间7kqas0il1#
好吧,这看起来可能有点奇怪,但是如果将lambda表达式转换为匿名类,错误就会消失:
这是因为lambda表达式的工作方式。
我认为下面从Java语言规范§ 15.27.2. Lambda Body中摘录的内容在这里是适用的:
与匿名类声明中出现的代码不同,lambda主体中出现的名称、
this
和super
关键字的含义,沿着被引用声明的可访问性,与周围上下文中的含义相同(除了lambda参数引入了新名称)。(强调我的。)
因此,被引用声明的可访问性实际上与您编写的代码相同:
现在,编译器抱怨的原因变得更加明显了:在赋值之前,您已经使用了
consumeSchedule
。这是从Java Language Specification § 16. Definite Assignment得出的:每一个由语句声明的局部变量(参见14.4.2节、14.14.1节、14.14.2节、14.20.3节)和每一个空的
final
字段(参见4.12.4节、8.3.1.2节),在其值发生任何访问时,都必须有一个 * 明确赋值 * 的值。(...)
每次存取局部变量或空白
final
字段x
时,必须在存取前明确指定x
,否则会发生编译时期错误。