Java條件編譯是什麼?
一、概述
條件編譯是指源程式的程式碼行,可以在滿足一定條件的情況下才進行編譯,而未選中的原始碼,不會生成中間碼或機器碼,即部分內容參與編譯。
條件編譯的好處: 對於不同硬體平臺或者軟體平臺,或者不同功能模組的程式碼,編寫到在同一個原始檔,從而方便程式的維護和移植。
很多程式設計語言都提供條件編譯的功能,比如C/++c採用前處理器指示符來達到條件編譯。而Java語言並沒有提供直接的前處理器,那麼Java是不是就沒有條件編譯呢?先告訴大家,答案是Java存在條件編譯,在這之前先說說C/C++的條件編譯。
二、C/C++條件編譯
對於C/C++,常見的預處理指令:
#define 巨集定義 #undef 取消已存在的巨集定義 #if 如果條件為真,則編譯後面的程式碼 #ifdef 如果巨集已定義,則編譯後面的程式碼 #ifndef 如果巨集未定義,則編譯後面的程式碼 #elif 如果前面的#if條件為假,並且當前條件為真,則編譯後面的程式碼 #endif 結束前面的#if……#else條件編譯語句塊 複製程式碼
條件編譯常見形式:
(1) 當通過#define已定義過該 識別符號,則程式編譯階段會選擇編譯程式碼段1,否則編譯程式碼段2
#ifdef 識別符號
程式碼段
1
#
else
程式碼段
2
#endif
(2) 當通過#define未定義過該 識別符號,則程式編譯階段會選擇編譯程式碼段1,否則編譯程式碼段2。功能正好與(1)相反
#ifndef 識別符號
程式碼段
1
#
else
程式碼段
2
#endif
(3) 當 表示式為真,則程式編譯階段會選擇編譯程式碼段1,否則編譯程式碼段2
#
if 表示式
程式碼段
1
#
else
程式碼段
2
#endif
三、Java條件編譯
Java語法的條件編譯,是通過判斷條件為常量的 if語句實現的。其原理是Java語言的語法糖,根據if判斷條件的真假,編譯器直接把分支為false的程式碼塊消除。通過該方式實現的條件編譯,必須在方法體內實現,而無法在正整個Java類的結構或者類的屬性上進行條件編譯,這與C/C++的條件編譯相比,確實更有侷限性。在Java語言設計之初並沒有引入條件編譯的功能,雖有侷限,但是總比沒有更強。
反編譯分析技術:
對於Debug.java檔案,執行:
javac Debug
.java
//編譯後 生成Debug.class檔案
javap
-c Debug
.class
//通過javap,反編譯class檔案
接下來,展開幾項對比分析:
3.1 final對比
該對比項是針對是否採用final變數與非final變數的對比:
原始碼:
// 空方法
public
void
voidMethod
(
)
{
}
//java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答!
//final常量
private final boolean
FINAL_FLAG_FALSE
=
false
;
public
void
constantFalseFlag
(
)
{
if
(
FLAG_FALSE
)
{
System
.out
.
println
(
"debug log..."
)
;
}
}
// 非final
private boolean falseFlag
=
false
;
public
void
falseFlag
(
)
{
if
(
falseFlag
)
{
System
.out
.
println
(
"debug log..."
)
;
}
}
反編譯解析後的結果如下:
// 空方法
public
void
voidMethod
(
)
;
Code
:
0
:
return
//final常量
public
void
constantFalseFlag
(
)
;
Code
:
0
:
return
// 非final
public
void
falseFlag
(
)
;
Code
:
0
: aload_0
1
: getfield #
3
// Field falseFlag:Z
4
: ifeq
15
7
: getstatic #
5
// Field java/lang/System.out:Ljava/io/PrintStream;
10
: ldc #
6
// String debug log...
12
: invokevirtual #
7
// Method java/io/PrintStream.println:(Ljava/lang/String;)V
15
:
return
從反編譯的Code欄位,可以看出constantFalseFlag()方法體內的內容經過編譯後,對於常量false分支,是不可達分支,則在編譯成class位元組碼檔案時剪出該分支,最終效果等價於voidMethod()。而對於falseFlag()方法,則多了5條指令。
可見,對於常量為false的if語句,由於恆為false,等同於條件編譯的功能。
另外除了反編譯的方式來對比分析,如果不瞭解反編譯後的語法,還可以簡單地對比編譯後的.Class檔案的大小,也會發現if(false){}內部的程式碼塊會自動剪除。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2846996/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Rust 條件編譯Rust編譯
- go怎麼沒有條件編譯Go編譯
- doxygen 宏定義/宏編譯/條件編譯/預處理/預編譯 不處理、忽略條件、分析所有條件、滿足所有條件的方法編譯
- Rust 交叉編譯與條件編譯總結Rust編譯
- uni-app 條件編譯APP編譯
- C語言 - 條件編譯C語言編譯
- PLSQL Language Reference-PL/SQL語言基礎-條件編譯-條件編譯指令限制SQL編譯
- PLSQL Language Reference-PL/SQL語言基礎-條件編譯-條件編譯舉例SQL編譯
- .NET探索平臺條件編譯編譯
- Java學習需要具備什麼條件?Java
- 「譯」編寫更好的 JavaScript 條件式和匹配條件的技巧JavaScript
- 【C進階】22、條件編譯分析編譯
- 條件編譯符號與公佈編譯符號
- oracle 10g的條件編譯Oracle 10g編譯
- 智慧經營的條件和標準是什麼?
- Rust 在 cargo 中進行條件編譯RustCargo編譯
- Java是什麼_Java是做什麼的?Java
- 【譯】什麼是Blob?
- 前端學習(2366):條件編譯跨端相容前端編譯跨端
- Android編譯時註解框架系列1-什麼是編譯時註解Android編譯框架
- 什麼是郵件營銷
- 學完Java後找工作難嗎?需要滿足什麼條件?Java
- 【譯】為什麼ReasonReact是編寫React的最佳方式React
- 【譯】編寫更好JavaScript條件語句的5個技巧JavaScript
- C語言的條件編譯#if, #elif, #else, #endif、#ifdef, #ifndefC語言編譯
- 條件編譯、多檔案程式設計、結構體編譯程式設計結構體
- 【譯】Dart | 什麼是MixinDart
- 【譯】到底什麼是DOM
- [譯] 究竟什麼是DOM?
- c++進階(一)C語言條件編譯及編譯預處理階段C++C語言編譯
- 面試官:Java從編譯到執行,發生了什麼?面試Java編譯
- 寫好了.java編譯成.class,用什麼打包生成.exeJava編譯
- 件斷點到底是什麼?斷點
- 什麼是郵件伺服器伺服器
- 儲存過程裡呼叫編譯自己是什麼情況?儲存過程編譯
- Java是什麼? Java適用於什麼工作?Java
- 問答丨演算法工程師具體是做什麼的? 需要什麼樣的條件?演算法工程師
- 等保測評證書是由什麼部門發的?申請需要滿足什麼條件?