2014-02-24 19 views
0

我寫了下面的代碼,我注意到在警告消息的區別:方法引用是否擺脫了可覆蓋的方法調用?

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

不,這兩種用法沒有區別。特別是在這種情況下,您可以從參考方法爲abstract的事實中得出答案。任何代碼調用此方法必須結束在一個重寫的方法。

在這種特殊情況下,IDE在兩種情況下都應警告您 - 不是因爲您在構造函數中調用了可重寫方法,而是因爲this實例從構造函數中轉義。

無論您使用哪種構造,lambda或方法引用,代碼都不是線程安全的。您甚至冒着開始線程中斷的風險,因爲它們可能會爲您的鎖對象看到null值。

把它放在一行中,永遠不要從構造函數中啓動線程。