[英]Why are there Debug & Release builds for .Net, but not for Java?
[英]DEBUG and RELEASE builds in Java (Eclipse)?
Java和Eclipse的新手(但在Visual Studio和Delphi方面經驗豐富)。 使用Eclipse Mars(4.5)並且無法找到如何設置構建配置(DEBUG或RELEASE)。 幾個相關問題:
{$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
{$IFDEF DBG} CallDebugFunction(); {$ELSE} CallReleaseFunction(); {$ENDIF};
java中並不完全支持DEBUG / RELEASE。 但是有一些事實是有用的記憶,還有一些其他方法來完成同一件事的一部分。
java的創建者認為,無論外部因素如何,每個編譯單元產生完全相同的字節碼都有很大的優點,因此Java沒有預處理器。
java最接近您熟悉的DEBUG / RELEASE類型是assert
關鍵字。 您可以通過向VM提供-assertionsenabled
(簡稱-ea
)參數來控制是否評估斷言。 閱讀它,並閱讀有關如何將參數傳遞給VM的信息。
請注意,VM參數是運行時參數,它們與編譯器無關,這意味着編譯器將始終將斷言發送到字節碼中,如果不提供-ea
,則運行時將避免對它們進行評估。 因此,至少仍然會有一個隱藏的if( assertionsEnabled ) { ... }
語句來執行每個斷言。
另一件事值得記住的是, public static final
變量被當作編譯時間常數, 並且編譯器可避免發射用於由受控源代碼中的任何字節碼if( false )
子句。 但是,源代碼將始終被編譯,因此它必須是正確的,盡管事實上不會生成字節碼。
因此,您可以將全局變量定義為public static final boolean DEBUG = true
來控制所有調試代碼,但您必須在源代碼中手動更改它並重建項目以生成發布版本; java特別避免提供任何其他方法來實現這一點。
另外,請注意if( false )
(以及擴展if( DEBUG )
)將產生關於條件始終為true或始終為false的警告,因此我不喜歡使用它。
java的哲學是我們通常不關心這種偏執程度的性能,以至於想要完全控制DEBUG和RELEASE之間微小的性能差異。 一般來說, assert
關鍵字就是所需要的,實際上(令我沮喪的是)大多數java人甚至不會因為各種(跛腳,恕我直言)原因而使用斷言。
至於發出調試信息,絕大多數調試信息都是生成的,因為它必須在運行時通過反射可用。 我知道你可以控制的一件小事: -parameters
編譯器選項,但它實際上是無關緊要的,編譯器的未來版本可能會棄用該選項並包含它作為標准控制的功能行為。
這也意味着java代碼可以比C ++代碼更容易進行逆向工程,因此存在java混淆器,它們在將代碼發送到java編譯器之前通過標識符修改階段傳遞代碼,從而減少數量字節碼文件中的有用信息。
您可能很高興知道由於JITting這一切都不是太糟糕:VM將字節碼編譯成機器代碼,並且在該階段進行了許多優化,因此您始終可以從中受益,而不僅僅是在RELEASE上。
至於檢測斷言是否已啟用,您可以使用以下代碼:
static boolean areAssertionsEnabled()
{
//noinspection UnusedAssignment
boolean b = false;
//noinspection ConstantConditions,AssertWithSideEffects
assert b = true;
//noinspection ConstantConditions
return b;
}
noinspection
檢測的東西用於抑制IntelliJ IDEA中的警告,這是一個遠遠優於Eclipse的Java IDE。 如果您堅持使用Eclipse,則必須為其找到等效的警告抑制機制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.