2012-12-09 36 views
0

我從編譯器理論的角度提出了更多的問題。爲什麼空指針分析未能考慮Assert.notNull()的影響?爲什麼Eclipse空指針分析未能識別斷言實用程序?

Code block show null reference access highlighted as error after Assert.notNull()

斷言方法是春天,它是爲實現:

public static void notNull(Object object, String message) { 
    if (object == null) { 
     throw new IllegalArgumentException(message); 
    } 
} 

public static void notNull(Object object) { 
    notNull(object, "[Assertion failed] - this argument is required; it must not be null"); 
} 

(這變得很煩人的,因爲如果我用這種說法公用事業,之後第一次訪問該變量該斷言會導致警告,這會阻止我實現無警告代碼。)

如果我完全內聯斷言例程,對a的訪問將不會被標記爲空指針訪問(在這種微不足道的情況下,它將成爲死代碼)。然而,一個靜態方法不能被重載(不是沒有字節碼提示),那麼編譯器設計者的POV的基本原理是不會進入空指針分析的方法調用中?

這只是表現關心,還是有阻止這一般做的事情?或者使其與其他編譯器檢查一致(死代碼分析也沒有考慮該方法)?

+0

問題是圖靈完整的一般,但更有限的解決方案几乎肯定是不切實際的。 –

+0

是的,由於停機問題,機器不能完全檢查非平凡的代碼,但許多代碼仍然可以靜態地完成。我可能是錯的,但我相信如果分析器內聯了所有的(靜態)方法調用,它應該能夠更好地處理像我這樣的許多微不足道的情況,但是由於某種原因,它只是在方法調用中停止。我承認雖然編譯後,目標函數可以很容易地被替換,導致驗證無效。 –

回答

0

這當然更多的是討論而不是問題。

  1. JAR的你編譯未必是你運行jar。特別是Assert將會是一個在生產環境中有不同實現的候選人。

  2. 空指針錯誤會比死代碼錯誤更好(在這裏)。

  3. eclipse編譯器在後臺不斷編譯。因此,智能支付與速度損失,這種檢查可能是更多的工具,如findbugs。 (想想所有庫調用,通過運行時異常可能會中斷控制流。)

3

爲什麼Eclipse空指針分析無法識別斷言實用程序?

因爲Eclipse空指針分析只考慮了它正在分析的方法的語句......而不是被調用方法的語義。 (我當然不希望/希望Eclipse編譯器的分析代碼治療Spring斷言方法作爲一種特殊情況。)

這變得很煩人......

好關閉空分析然後! (應該有一個Eclipse編譯器首選項來執行此操作。)

或者更改您的代碼,使其值不總是null。或刪除引用null引用的(動態)不可訪問的語句。

說實話,你的例子非常人造,我無法想象任何人在真正的代碼中做這樣的事情。沒有「修正」,不會改變你的代碼的含義。我想這是不是你真正的代碼的情況下...


當你想想看,這裏的問題是大致相當於檢測未初始化的變量,並在Java中的語句不可達的問題。 Eclipse正在採用與Java/JLS相同的解決方案。


至於想法,Eclipse的應該使用最先進的非本地分析代碼狀態是......我不同意。這將使Eclipse的交互式編譯變得緩慢,如糖蜜。

還有其他原因沒有實現這一點,包括:

  • 的事實,這個問題不能在一般情況下(停機問題)來解決,
  • 的事實,這是一個技術上的困難問題在理論上是可以解決的情況下解決,
  • 的事實,額外的代碼將需要維護,
  • 的事實功能將有效用有限 。 (我的意思是說,你真的真的認爲值得花費許多人工月份來修復一小部分用戶的輕微惱怒,這些用戶可以在幾秒鐘內爲自己解決......通過調整編譯器偏好? )

但是,如果您對此感到強烈,那麼您可以自由開發和測試分析代碼並將其提供給Eclipse項目。

+0

我不能接受兩個答案,所以我給了你一個投票。喬普的回答是更簡潔恕我直言。 –