2013-05-31 85 views
3

斷言在Java編譯到私人合成靜態布爾加入到測試 - 的提議是很好的記錄在這裏:

JSR Assertion Proposal

在這裏面,我們創建

final private static boolean $ assertionsEnabled = ClassLoader.desiredAssertionStatus(className);

然後

assert(X)
成爲
if ($assertionsEnabled && !x) { throw }

這是非常合情合理的;)

然而,我發現我竟然得到的是

public void test1(String s) { 
    assert (!s.equals("Fred")); 
    System.out.println(s); 
} 

成爲

static final /* synthetic */ boolean $assertionsDisabled; 

public void test1(String s) { 
    if ((!(AssertTest.$assertionsDisabled)) && (s.equals("Fred"))) { 
     throw new AssertionError(); 
    } 
    System.out.println(s); 
} 

static { 
    AssertTest.$assertionsDisabled = !(AssertTest.class.desiredAssertionStatus()); 
} 

我找不到任何有關他們爲什麼的文檔nt有一個負面測試,而不是一個積極的測試 - 即最初的提議獲取了assertionsENABLED,現在我們使用assertionsDISABLED。 (可能!)生成更好的分支預測,但這似乎是一個非常蹩腳的猜測 - Java哲學(幾乎)總是使字節碼變得簡單,並讓JIT梳理優化。

(注意,這不是一個關於斷言是如何工作的問題 - !我知道:))

(順便說一句,這是相當有趣的是,這會導致不正確的教程6.2.1 of this tutorial! ,有人引用了a previous SO question on assertions的迴應得到了錯誤的測試意義!:)

任何想法?

回答

1

該布爾實際上是用一個整數實現的。有一種常見的認爲,與零比較更快,但我沒有看到任何理由使用禁用,而不是啓用。

恕我直言,因爲false是布爾值的默認值,所以我嘗試選擇一個默認值爲false的標誌。在這種情況下,$assertionsEnabled會更有意義。

+0

確實。這使得使用$ assertionsDisabled更容易混淆決定;)另外(很明顯),這個變量在JITted代碼中總是不變的摺疊。 (通過-XX:+ PrintAssembly驗證) – lab27

1

雖然它看起來像有就是當你看反編譯java源正在做多餘的工作 - 你不能靠這個 - 你需要看看字節代碼級

看一看字節碼都Eclipse編譯器和Oracle的javac農產品:

    #0: getstatic Test.$assertionsDisabled 
        #3: ifne #23 
        (assertion code) #6: aload_1 
        (assertion code) #7: ldc "Fred" 
        (assertion code) #9: invokevirtual String.equals(Object) 
        (assertion code) #12: ifeq #23 
        (assertion code) #15: new AssertionError 
        (assertion code) #18: dup 
        (assertion code) #19: invokespecial AssertionError.<init>() 
        (assertion code) #22: athrow 
        #23: getstatic System.out (PrintStream) 
        #26: aload_1 
        #27: invokevirtual PrintStream.println(String) 
        #30: return 

請注意字節碼#3 - 它不需要反轉Test.$assertionsDisabled價值,它只需要進行單一的負面測試(即如果它是字節代碼級別的負面測試或正面測試,則沒有任何區別)

總之,它的實施非常有效,並且不會執行任何冗餘工作。