方法引用是否摆脱了可覆盖的方法调用?

时间:2014-02-24 10:10:22

标签: java constructor lambda override java-8

我正在编写以下代码,并注意到警告消息的不同之处:

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是否未配置为警告方法引用?

1 个答案:

答案 0 :(得分:1)

不,这两种用法没有区别。特别是在这种情况下,您可以从引用的方法是abstract的事实中得出答案。调用此方法的任何代码必须以重写方法结束。

在这种特殊情况下,IDE应该在两种情况下都警告你 - 不是因为你在构造函数中调用了可覆盖的方法,而是因为this实例从构造函数中逃脱了。

使用哪个构造,lambda或方法引用无关紧要,代码不是线程安全的。您甚至冒着启动线程中断的风险,因为他们可能会看到锁定对象的null值。

要将它放在一行中,切勿从构造函数中启动线程。

相关问题