作者: 許裕永
資料的運算,自然要利用運算符號。兩個資料用一個運算符號串聯起來,即為一個運算式,一句敍述句可以是多個運算式的串聯。例:a=b+c+d;這一句敍述
句包含了3個運算式;它會先把b和c做加的運算,再把運算後的值和d做加的運算,再把運算後的值指派給a,所以它是二個算術運算式及一個指派運算式串聯的
敍述句。而運算的順序,除了後續部份有特別介紹的運算符號之外,不外乎先乘除後加減,由左向右,括號先算。不同資料型別的資料是無法運算的。所以,當運算式要運算不同資料型別的資料時,Java會先依上一章所敍述之自動轉換的原則,將資料轉換為相同的資料型別再行運算,若有無法執行自動轉換的資料,則會產生編譯時期錯誤。
符號 | 意義 | 範例 |
+ | 求和 | a+b |
- | 求差;負值 | a-b,-b |
* | 求積 | a*b |
/ | 求商 | a/b |
% | 求餘數 | a%b |
++ | 增量(加1) | a++,++a |
── | 減量(減1) | a──,──a |
用+、-、*、/來運算數值。特別要注意的是:整數運算式中若有byte或short型別的變數時,此運算式運算後的型別為int。原理很簡單:因為 byte或short的最大值或最小值無論是與任何數值做運算,均可能會超過其最大值或最小值的範圍。總而言之:整數運算式的預設型別為int。
例:
byte a=3;
byte b=8+8; //此句正確
byte c=a+8; //此句編譯錯誤
第三句敍述句的算術運算式中有byte型別的變數a,所以運算後的值為int型別,無法指派給byte型別的變數c。
另一個重點,是強制轉型的使用。例:“(int)a+b;”與“(int)(a+b);”所轉換的對象是不一樣的。前一句是轉換a的值後再與b做加的運算;後一句是先執行a+b的運算後再轉換。
例:
int a=5;
byte b=(byte)a+8; //編譯錯誤
byte c=(byte)(a+8); //正確
第二行敍述句中,int型別變數a會先轉為byte型別,再與8做加的運算。但byte型別的變數做加的運算,其運算結果還是int型別,所以無法指派給byte型別的變數b。
1-2 +:
若此運算符號的左值或右值中有字串資料(置於“”中之資料)時,則所有型別的資料均會自動轉型為字串資料(含布林值及參考資料型別),再進行字串串聯的運算。(參考資料型別會呼叫方法toString(),後續章節介紹)
例:
System.out.println(“1”+2+3);
此句字串“1”先和數值2運算,串聯為“12”後再與數值3運算,結果為“123”
System.out.println(1+2+”3”);
此句數值1先和數值2運算為數值3後再與字串“3”運算,結果為“33”
1-3 /:
此運算符號要注意:整數運算的結果還是整數,不會取小數點,更不會自動四捨五入。
例:
int a=8/3;
float b=8/3; //8/3運算結果2為int型別
System.out.println(b); //值為2.0
1-4 %:
求餘數的運算。一般用來判斷除數與被除數之間是否為倍數關係。例:8%2之值為0,所以8是2的倍數;也可以用來控制整數數值的範圍,讓該數值介於某一特定範圍之中。例:任意整數%8之值必定介於0到7之間。
1-5 ++:
增量運算,就是變數自己執行加1的運算。一般用來做計數的動作。
例一:
int a=8;
a++; //此句運算後a之值為9
++a; //此句運算後a之值為10
無論此符號置於變數前或變數後,均代表該變數自己執行加1的運算。
但若敍述句中還串聯其它運算符號時,增量運算符號置於變數前或變數後,將會改變該敍述句的運算結果。
例二:
int a=8;
int b=a++ +8; //++和+之間必須有空格
此例稱之為:「運算後增量」。運算指的是a與b做加的運算。增量指的是變數a自行加1的運算。此例中,增量運算符號置於變數a的後方,所以會先執行a與b加的運算之後,再執行變數a增量的運算,故稱之為運算後增量。因為執行a+b時,a尚未增量,所以b的值為16。
例三:
int a=8;
int b=++a+8;
此例稱之為:「運算前增量」。此例中,增量運算符號置於變數a的前方,所以會先執行變數a增量的運算之後,再執行a與b加的運算,故稱之為運算前增量。因為執行a+b時,a已經增量,所以b的值為17。
在這兩個範例中,我們必須注意:會因為增量符號的位置而改變的,並不是變數a的值(均為9)。而是指派運算符號(=)的右側,整個運算式的運算結果。另一個值得注意的是:增量符號若置於變數前方,則其運算順序,優先於任何其他運算符號。
1-6 ──:
減量運算,就是變數自己執行減1的運算。運算模式同增量運算,請自行練習。
符號 | 範例 | 同義敍述 |
= | a=b | |
+= | a+=b | a=a+b |
-= | a-=b | a=a-b |
*= | a*=b | a=a*b |
/= | a/=b | a=a/b |
%= | a%=b | a=a%b |
例:
byte a=3;
a=a+3; //編譯錯誤
a+=3; //正確
在此例中,a=a+3的指派運算符號(=)的右值為a+3,這是一個整數運算式,而整數運算式的預設型別為int,自然無法指派給byte型別的變數a。但a+=3的指派運算符號(+=)的右值為整數值3,不是運算式,屬於直接指派,所以正確。
條件運算式運算的結果便是布林值,只有兩種變化:true/false。
符號
|
意義
|
範例
|
==
|
等於
|
a==b
|
!=
|
不等於
|
a!=b
|
>
|
大於
|
a>b
|
>=
|
大於等於
|
a>=b
|
<
|
小於
|
a<b
|
<=
|
小於等於
|
a<=b
|
例:
boolean a=3>5; //a的值為false
boolean b=5<3; //b的值為false
boolean c=a==b;
boolean d=a=b;
第三行敍述句,是運算a==b的值,再將值指派給c,因為a和b均為false,所以c的值為true。而第四行敍述句,是把b的值指派給a,再指派給d,所以d,a,b之值均為false。
若要做布林值與布林值的運算(條件運算式與條件運算式的運算),或說是條件運算式的串聯運算時,就要使用邏輯運算符號。
符號
|
意義
|
範例
|
& | 長程 and | a<b & b<c |
&& | 短程 and | a<b && b<c |
| | 長程 or | a<b | a<c |
|| | 短程 or | a<b || a<c |
! | not | !(a==b) |
and的運算,必須是運算符號的左值(左側的條件運算式)及右值(右側的條件運算式)均為true時,其運算結果方為true。若左值及右值中任意一個或兩個的值均為false時,其運算結果便為false。
長程(&)及短程(&&)的差異在於:長程運算無論左值之運算結果為何,均會運算右值,而短程運算是在左值運算值為true時,才會運算右值。這是因為當左值為false時,則此邏輯運算的結果必然為false。使用短程運算,可以節省不必要的運算。
例一:
int a=5,b=6;
boolean c=a++>=b;
boolean d=--a>=b;
此例中,c的值為false:因為++是運算後增量,所以先運算a>=b的值為false,再運算a++,a的值便為6。d的值也是fasle:因為──是運算前減量,所以先運算──a,a的值便為5,再運算a>=b的值為false。
例二:
int a=5,b=5,c=5;
boolean d=a++>=b++ && b>c++;
此例運算結果為:a=6,b=6,c=6,d=true。其運算順序為:a>=b -> a++ -> b++ -> b>c -> c++。
例三:
int a=5,b=5,c=5;
boolean d=a++>b++ && b>c++;
此例運算結果為:a=6,b=6,c=5,d=false。其運算順序為:a>b -> a++ -> b++。因為&&是短程運算,而左值(a++>b++)為false,所以右值(b>c++)不運算。
例四:
int a=5,b=5,c=5;
boolean d=a++>b++ & b>c++;
此例運算結果為:a=6,b=6,c=6,d=false。其運算順序為:a>b -> a++ -> b++ -> b>c -> c++。因為&是長程運算,雖然左值(a++>b++)為false,但右值(b>c++)仍會運算。
4-2 |,||(or):
or的運算,只要運算符號的左值或右值其中一個為true時,其運算結果便為true。只有左值及右值的值均為false時,其運算結果才為false。
長程(|)及短程(||)的差異在於:長程運算無論左值之運算結果為何,均會運算右值,而短程運算是只有在左值運算值為false時,才會運算右值。這是因為當左值為true時,則此邏輯運算的結果必然為true,使用短程運算,可以節省不必要的運算。
例一:
int a=5,b=5,c=5;
boolean d=a++>b++ || b>c++;
此例運算果為:a=6,b=6,c=6,d=true。其運算順序為:a>b -> a++ -> b++ -> b>c -> c++。因為左值(a++>b++)之值為false所以會運算右值(b>c++)。
例二:
int a=5,b=5,c=5;
boolean d=a++>=b++ || b>c++;
此例運算果為:a=6,b=6,c=5,d=true。其運算順序為:a>b -> a++ -> b++。因為||是短程運算,而左值(a++>b++)之值為true,所以右值(b>c++)不會運算。
例三:
int a=5,b=5,c=5;
boolean d=a++>=b++ | b>c++;
此例運算果為:a=6,b=6,c=6,d=true。其運算順序為:a>b -> a++ -> b++ -> b>c -> c++。因為|是長程運算,雖然左值(a++>b++)之值為true,但右值(b>c++)仍會運算。
4-3 and及or的綜合使用:
若一個邏輯運算式中,串聯了and及or的運算符號,則其運算順序為:長程優先於短程,and優先於or。例:a>b && b>c || a>d;此敍 句會先執行a>b && b>c再將運算結果和a>d做or的運算。而因為都是短程運算符號,所以若a>b為false則b>c不會運算,而會直接運算 a>d;但若a>b為true且b>c為true,則a>d不會運算。
例一:
int a=5,b=5,c=5,d=5;
boolean e=a>b && b>c ||a++>d;
此例運算結果為:a=6,b=5,c=5,d=5,e=false。因為||的左值(a>b && b>c)為false,所以右值(a++>d)會運算。
例二:
int a=5,b=5,c=5,d=5;
boolean e=a>=b && b>=c ||a++>d;
此例運算結果為:a=5,b=5,c=5,d=5,e=true。因為||的左值(a>b && b>c)為true,所以右值(a++>d)不會運算。
4-4 !:
not的運算是:反轉運算符號右值之布林值。true轉為false;false轉為true。使用此運算符號時,須注意右側括號的使用。例:!a>b && b>c;及!(a>b && b>c)所反轉的對象是不一樣的。前一句是反轉a>b的值後,再與b>c做and的運算。後一句是反轉(a>b && b>c)運算後的值。
例:
boolean a=5>3;
boolean b=false;
boolean c=!a;
boolean d=!a && b;
boolean e=!(a&&b);
此例運算結果為:a=true,b=fasle,c=false,d=fasle,e=true。其中d的值是由!a(false)與b(false)做 and的運算。而e的值是運算!(true && false),括號中的值為false,再經過!的反轉運算,便得到true的運算結果。
語法:參考變數 instanceof 參考資料型別。
運算結果:true、false或編譯錯誤。
true:若參考變數所代表的物件,是參考資料型別的物件(物件多型)。
false:若參考變數所代表的物件,不是參考資料型別的物件(物件多型)。
編譯錯誤:若參考變數所代表的物件,和參考資料型別並非同一條繼承線(無父子關係),或沒有實作該界面。
例:
String s=new String(“Java”);
System.out.println(s instanceof String);//true
System.out.println(s instanceof Object);//true
Object o=new Object():
System.out.println(o instanceof String);//false
System.out.println(o instanceof Object);//true
Integer i=new Integer(8);
System.out.println(i instanceof Integer);//true
System.out.println(i instanceof Object);//true
//System.out.println(I instanceof String);本句註解取消將造成編譯錯誤
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。