今天的地鐵思考讓我想起一個之前學C語言的時候一直沒有驗證的事情:既生瑜何生亮?
- 平時寫代碼的時候,似乎並沒有太多的關注我應該選用什么條件判斷語句,感覺判斷條件或者兩條支路語句復雜就本能地if-else。
遇到一些數值,字符的按條件賦值輸出,就感覺if-else與這些簡短語句氣質不符,於是就用了三目運算符,使代碼更簡潔舒服。那么為什么有了if-else還要用?:呢,只是為了代碼更簡潔嗎,還是有什么不為人知的秘密[/嘿嘿] - 我打算稍稍探尋一下,從兩個方面來聊聊:效率和三目運算符的表達式特性
關於執行效率
- 我在網上一直沒有找到可靠的說辭或指南,有的說三目運算符效率高,還有的說一樣的,所以我來測測(測試環境可能由於我的電腦性能,給定參數原因,不能得出確切的結論,僅供參考)
- if-else
public static void main(String[] args) {
int num=1000;
System.out.println("if-else 運行時間:");
long totalTime=0L;
for (int i = 1; i <=10 ; i++) {
long startTime = System.nanoTime();
if (num>500&&num%3!=0&&num/10==100){
num=1001;
}else{
num=0;
}
long endTime = System.nanoTime();
long result = endTime - startTime;
totalTime+=result;
System.out.println("第"+i+"次: " + result + " 納秒");
}
System.out.println("平均時間為:"+totalTime/10+"納秒");
}
-
執行結果:
-
三目運算符 ? :
public static void main(String[] args) {
int num = 1000;
System.out.println("? : 運行時間:");
long totalTime = 0L;
for (int i = 1; i <= 10; i++) {
long startTime = System.nanoTime();
num = num > 500 && num % 3 != 0 && num / 10 == 100 ? 1001 : 0;
long endTime = System.nanoTime();
long result = endTime - startTime;
totalTime += result;
System.out.println("第" + i + "次: " + result + " 納秒");
}
System.out.println("平均時間為:" + totalTime / 10 + "納秒");
}
- 執行結果:
- 從結論上來看,平均執行時間並沒有太大差距,畢竟這里是以納秒為單位,所以,暫且以為
? :
僅僅是簡化代碼的吧 -
如果哪位大佬有專業的權威的見解,請一定來“拍一拍”我,讓我的石頭落下。
表達式特性(BNP : binary numeric promotion)
-
二進制數值提升
- 在三目運算符中的第二和第三表達式的類型依據數值范圍大的那個,將一個小數值的類型范圍擴大,比如16位提升到32位,32位到64位,直觀一點就是short提升到int,int提升到long,不同類型之間也可以提升,但是不一定是往兩個其中的一個走,也有short和char,最終表達式是int的情況。 -
舉幾個栗子就比較清楚了
-
1,參數是int和byte,但是整個表達式的類型卻是int
-
2,參數:int,char 表達式類型:int
-
3,參數:short,char 表達式類型:int
-
4,參數:int,float 表達式類型:float (如果字節數相同,會提升到浮點數)
-
5,參數:int,long 表達式類型:long
-
6,參數:long,double 表達式類型:double (如果字節數相同,會提升到浮點數)
-
7,同上的包裝類,包裝類在運算時自動拆箱,和基本數據類型結果無異
-
8,更具體一點,這里判斷執行第三表達式,可因為第二表達式是浮點數,所以輸出的9不是int的9而是浮點數的9.0
int number = 1000;
System.out.println(number<0?10.0:9);
console:
這么看來和數據類型的自動類型轉換似乎是一致的
總的來看,if-else和三目運算符並沒有在今天分出勝負,我們依然可以按照之前的習慣寫代碼,只是讓我們之后寫代碼的不用再猶豫和糾結用什么好,不用再想起他們倆之間的糾葛。在實際生產環境中按照各自團隊規范來就好。這些也是最近才發現的,雖然感覺很少用到,但這不是目的。我們遇到的東西那么多,不會每樣都能用到你的程序里,只是為了在下次遇到此類問題Bug時,能夠游刃有余,這就是我們程序員鴨,突然感覺這篇文章啥也沒做,但是卻也不是啥也沒做,哈哈奇怪咧。
- 參考文檔:Java語言規范--https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-ConditionalExpression
至此,若有紕漏,望各位不吝賜教