我正在编写以下代码,并注意到警告消息的不同之处:
public abstract class Yielder<E> implements Iterator<E> {
private final Object lock = new Object();
private final Thread yieldThread;
private E element;
public Yielder() {
this.yieldThread = new Thread(this::getYields);
startThreads();
}
private void startThreads() {
yieldThread.start();
}
@Override
public boolean hasNext() {
//impl
}
@Override
public E next() {
//impl
}
protected void yield(final E yield) {
//impl
}
abstract protected void getYields();
}
public class IncrementingYielder extends Yielder<Integer> {
@Override
protected void getYields() {
int i = 0;
while (true) {
yield(i++);
}
}
}
当在Yielder<E>
的构造函数中时,如果我写:
this.yieldThread = new Thread(() -> getYields())
,我收到了警告Overridable method call in constructor
。this.yieldThread = new Thread(this::getYields)
,然后一切都很好。这里真的有区别吗?或者,Netbeans 8.0 Beta是否未配置为警告方法引用?
答案 0 :(得分:1)
不,这两种用法没有区别。特别是在这种情况下,您可以从引用的方法是abstract
的事实中得出答案。调用此方法的任何代码必须以重写方法结束。
在这种特殊情况下,IDE应该在两种情况下都警告你 - 不是因为你在构造函数中调用了可覆盖的方法,而是因为this
实例从构造函数中逃脱了。
使用哪个构造,lambda或方法引用无关紧要,代码不是线程安全的。您甚至冒着启动线程中断的风险,因为他们可能会看到锁定对象的null
值。
要将它放在一行中,切勿从构造函数中启动线程。