作符
主要操作符:+、-、*、/、=、++、--、+=、-=、==、!=、&&、||、!、&、^、~、>=、<=、>、< …..
幾乎所有的操作符只能夠操作”基本數據類型”,=、==、!=可以操作所有的數據類型及對象
String類型支持+、+=連接操作
優先級問題:
此處注意:任何數據類型與String類型進行+連接都將會先將其他的數據類型轉變為String在連接成String類型
而此時的+不再會做任何的計算
demo:
int i = 1; int j = 2; System.out.println("result:" + i + j);//result:12 System.out.println("i == j : " + i == j);// × System.out.println("i == j : " + (i == j));// √ |
關于賦值操作符:取右邊的值(即右值),把它復制給左邊(即左值)。右值可以是任何常數、變量、或者表達式(只要它能夠生成一個值就行)。但左值必須是一個明確的、已命名的變量,也就是必須有一個物理空間可以存儲等號右邊的值
基本數據類型賦值:直接將一個地方的值復制到另外一個地方
a = b;//b的內容復制給a,若修改a或b其中的一個值,另外一個值不會受到任何影響
對象賦值:真正操作的是對象的引用,
所以將對象賦值給另外一個對象實際上是將一個對象的引用復制到另外一個地方
它們其實指向的是內存中的同一塊內容
demo:ObjectRefrenceTest.java
packagejavabase.flowcontrol; publicclassObjectRefrenceTest{ /** *對象賦值測試 */ publicstaticvoidmain(String[]args){ Rowidrowid=newRowid(); rowid.rowid="LIYIHUIZHANYUANYING"; TiptopERPtopprod=newTiptopERP(); TiptopERPtoptest=newTiptopERP(); topprod.seesionId=0; topprod.DBType="Oracle"; topprod.rowid=rowid; toptest=topprod;//對象賦值 System.out.println("Before:"); System.out.println("topprod:"+topprod.seesionId+topprod.DBType+topprod.rowid.rowid); System.out.println("toptest:"+toptest.seesionId+toptest.DBType+toptest.rowid.rowid); System.out.println("Afterchangetopprodobject:"); //toptest.DBType="Informix"; topprod.DBType="Informix"; topprod.rowid.rowid="5201314131413141314";//此處改變了topprod.rowid對象的成員變量 System.out.println("topprod:"+topprod.seesionId+topprod.DBType+topprod.rowid.rowid); System.out.println("toptest:"+toptest.seesionId+toptest.DBType+toptest.rowid.rowid); System.out.println("-----------------------------"); TiptopERPerp=newTiptopERP(); TiptopERPmrpII=newTiptopERP(); erp.seesionId=2; erp.DBType="DB2"; erp.rowid=rowid;//此處直接將先前的rowid對象直接賦值給erp.rowid mrpII.seesionId=erp.seesionId;//對象成員變量int單獨賦值 mrpII.DBType=erp.DBType;//對象成員變量String單獨賦值 mrpII.rowid=erp.rowid; System.out.println("Before:"); System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid); System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid); System.out.println("Afterchangrowid:"); erp.rowid.rowid="LIYIHUIZHANYUANYING";//此處改變了erp.rowid對象的成員變量 System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid); System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid); System.out.println("Afterchangeerpobject:"); erp.seesionId=1; erp.DBType="Mysql"; erp.rowid.rowid="5201314131413141314";//此處改變了erp.rowid對象的成員變量 System.out.println("erp:"+erp.seesionId+erp.DBType+erp.rowid.rowid); System.out.println("mrpII:"+mrpII.seesionId+mrpII.DBType+mrpII.rowid.rowid); } } classTiptopERP{ intseesionId;//基本數據類型 StringDBType;//String對象 Rowidrowid;//一般對象 } classRowid{ Stringrowid; } /*輸出結果: Before: topprod:0OracleLIYIHUIZHANYUANYING toptest:0OracleLIYIHUIZHANYUANYING Afterchangetopprodobject: topprod:0Informix5201314131413141314//rowid值改變了 toptest:0Informix5201314131413141314//rowid值改變了 ----------------------------- Before: erp:2DB25201314131413141314//rowid值改變了 mrpII:2DB25201314131413141314//rowid值改變了 Afterchangrowid: erp:2DB2LIYIHUIZHANYUANYING//rowid值改變了 mrpII:2DB2LIYIHUIZHANYUANYING//rowid值改變了 Afterchangeerpobject: erp:1Mysql5201314131413141314//rowid值改變了 mrpII:2DB25201314131413141314//rowid值改變了 */ |
demo:PassObject.java
package javabase.flowcontrol; class Letter{ char c; } public class PassObject { /** *對象引用 */ static void f(Letter y){ y.c = 'z'; } public static void main(String[] args) { Letter x = new Letter(); x.c = 'a'; System.out.println("before:x.c = " + x.c); f(x); System.out.println("after:x.c = " + x.c); } } /*輸出結果: before:x.c = a after:x.c = z */ |
此類對于傳遞對象引用而引起的問題在Think In Java被稱做”別名問題”
使用中應注意此類陷阱
++或--:前綴++/--先運算再生成值,后綴++/--先生成值再運算
==與equals:
比較2個實際值是否相等:對象用equals,基本數據類型用==
比較對象的地址是否相等:對象/基本數據類型都用==
demo:EqualsTest.java
package javabase.flowcontrol; class ValueInt{ int id; } class ValueString{ String id; @Override public boolean equals(Object obj) { boolean instanceFlag; instanceFlag = obj instanceof ValueString; if(!instanceFlag) return super.equals(obj); else{ ValueString vTemp = (ValueString)obj; if(vTemp.id.equals(this.id)){ return true; } return false; } } } public class EqualsTest { /** * ==操作符、equals的區別 */ public static void main(String[] args) { //基本數據類型 int i1 = 100; int i2 = 100; System.out.println("i1 == i2 : " + (i1 == i2)); //對象 Integer n1 = new Integer(250); Integer n2 = new Integer(250); System.out.println("n1 == n2 : " + (n1 == n2)); System.out.println("n1 equals n2 : " + n1.equals(n2)); //自定義對象 ValueInt vInt1 = new ValueInt(); ValueInt vInt2 = new ValueInt(); vInt1.id = vInt2.id = 32; System.out.println("vInt1 == vInt2 : " + (vInt1 == vInt2)); System.out.println("vInt1 equals vInt2 : " + vInt1.equals(vInt2)); ValueString vString1 = new ValueString(); ValueString vString2 = new ValueString(); vString1.id = vString2.id = "李藝輝"; System.out.println("vString1 == vString2 : " + (vString1 == vString2)); System.out.println("vString1 equals vString2 : " + vString1.equals(vString2)); //String 對象比較復雜,后面會有String對象的詳細解析 } } /*輸出結果: i1 == i2 : true n1 == n2 : false n1 equals n2 : true vInt1 == vInt2 : false vInt1 equals vInt2 : false //這是因為equals默認行為是比較2個對象的引用 vString1 == vString2 : false vString1 equals vString2 : true //復寫該對象的equals方法后的比較 */ |
邏輯操作符:&&、||、!
邏輯操作只可以應用于布爾值,注意邏輯操作的”短路”情況
test(1) && test(2) && test(3) //順序判斷,只要前面有一個test為假后面的判斷就不需要執行了
test(1) || test(2) || test(3) //順序判斷,只要前面有一個test為真后面的判斷就不需要執行了
按位操作符:位與(&)、位或(|)、位非(~)、
有符號位左移(<<):低位補0
有符號位右移(>>):若符號為正則高位補0,若符號為負則高位補1
無符號位左移(<<<):無論正負低位全部補0
無符號位右移(>>>):無論正負高位全部補0
如果對char、byte、short類型數值進行移位處理,那么在移位之前它們都將先被轉換為int類型,
并且得到的結果也是int類型,且移位后的數值結果只有低5位才有用(int類型為2的5次方)
三元操作符:
boolean-exp ? value0 : value1
如果布爾表達式boolean-exp為true則計算value0,否則計算value1
控制執行流程
關鍵字:Java控制執行流程主要涉及的關鍵字if-else、while、do-while、for、return、break、continue
Java并不支持goto語句,但是在java中仍然保留了goto
條件判斷:所有條件判斷都利用條件表達式的真或假來決定執行流程
注意:java不允許將一個數字等非boolean值作為布爾值使用,如果要在布爾測試中使用一個非布爾值則首先必須用一個條件表達式將其轉換成布爾值。
Ex:a是非boolean類型值 if(a)×à if(a!=0) √
while:先判斷條件表達在執行循環體,條件為false則一次都不執行
do-while:先執行循環體,再判斷條件表達式,因此至少會執行一次
for語句:for(int i = 1, j = 5;i < 5;i++,j = i+2)
for語句初始化部分實際上可以定義任意數量的變量,注意:但是這些變量都必須是同一種數據類型
for語句中可以使用一系列有逗號表達式分隔的語句
增強行的for循環:for(char c : “hello world”.toCharArray())
如果for循環有索引或是步進,則上述增強行的for循環不能夠直接滿足需求
Think in java 建議自寫一個range()方法配合增強型的for循環
import static net.mindview.util.range.* //此包需從www.mindview.com上下載 Ex:for(int i : range(10)) //range(10)返回數組,元素為0..9 for(int i : range(5,10)) //range(5,10)返回數組,元素為5..9 for(int i : range(5,10,3)) //range(5,10,3)返回數組,元素為5..10 step 3 while(true) = for(;;) switch .. case...break語句: switch(integral-selector) //integral-selector:選擇因子必需是int或是char那樣的整數值 case integral-value1:statement:break; // Default:statement; |
單一case satatement后面需有break,避免case穿透到下一case statement
return:指定一個方法的返回值,并退出該方法。
如果一個方法聲明有非void的返回值,那么必須確保每一條代碼路徑都將返回一個值
break:終止當前循環體
continue:停止循環體的當前迭代,然后退回循環起始處,開始下一次迭代
goto:雖然java不再使用goto語句,但是依然保留了goto作為關鍵字
在java中如果想實現goto一樣跳轉語句的功能可以使用標簽編程
請看如下demo:GotoLabel.java
package javabase.flowcontrol; public class GotoLabel { /** *java標簽編程應用 */ public static void main(String[] args) { int i = 0; outer: //此處不可以寫其它的任何代碼 //System.out.println("outer man!"); for(;true;){ inner: //此處不可以寫其它的任何代碼 //System.out.println("innter man!"); for(;i<10;i++){ System.out.println("i = " + i); if(i == 2){ System.out.println("continue"); continue; } if(i == 3){ System.out.println("break"); i++; break; } if(i == 7){ System.out.println("continue outer"); i++; continue outer; } if(i == 8){ System.out.println("break outer"); break outer; } for(int k = 0; k < 5; k++){ if(k == 3){ System.out.println("continue inner"); continue inner; } } } System.out.println("hello world"); } System.out.println("fuck in java"); } } /*輸出結果: i = 0 continue inner i = 1 continue inner i = 2 continue i = 3 break hello world i = 4 continue inner i = 5 continue inner i = 6 continue inner i = 7 continue outer i = 8 break outer fuck in java */ |
一般的continue會退回最內層循環的開頭,并繼續執行
帶標簽的continue會到達標簽的位置,并重新進入緊接在那個標簽后面的循環
一般的break會中斷并跳出當前的循環體
帶標簽的break會中斷并跳出標簽所指的循環
三元操作符:
boolean-exp ? value0 : value1
如果布爾表達式boolean-exp為true則計算value0,否則計算value1
控制執行流程
關鍵字:Java控制執行流程主要涉及的關鍵字if-else、while、do-while、for、return、break、continue
Java并不支持goto語句,但是在java中仍然保留了goto
條件判斷:所有條件判斷都利用條件表達式的真或假來決定執行流程
注意:java不允許將一個數字等非boolean值作為布爾值使用,如果要在布爾測試中使用一個非布爾值則首先必須用一個條件表達式將其轉換成布爾值。
Ex:a是非boolean類型值 if(a)×à if(a!=0) √
while:先判斷條件表達在執行循環體,條件為false則一次都不執行
do-while:先執行循環體,再判斷條件表達式,因此至少會執行一次
for語句:for(int i = 1, j = 5;i < 5;i++,j = i+2)
for語句初始化部分實際上可以定義任意數量的變量,注意:但是這些變量都必須是同一種數據類型
for語句中可以使用一系列有逗號表達式分隔的語句
增強行的for循環:for(char c : “hello world”.toCharArray())
如果for循環有索引或是步進,則上述增強行的for循環不能夠直接滿足需求
Think in java 建議自寫一個range()方法配合增強型的for循環
import static net.mindview.util.range.* //此包需從www.mindview.com上下載 Ex:for(int i : range(10)) //range(10)返回數組,元素為0..9 for(int i : range(5,10)) //range(5,10)返回數組,元素為5..9 for(int i : range(5,10,3)) //range(5,10,3)返回數組,元素為5..10 step 3 while(true) = for(;;) switch .. case...break語句: switch(integral-selector) //integral-selector:選擇因子必需是int或是char那樣的整數值 case integral-value1:statement:break; // Default:statement; |
單一case satatement后面需有break,避免case穿透到下一case statement
return:指定一個方法的返回值,并退出該方法。
如果一個方法聲明有非void的返回值,那么必須確保每一條代碼路徑都將返回一個值
break:終止當前循環體
continue:停止循環體的當前迭代,然后退回循環起始處,開始下一次迭代
goto:雖然java不再使用goto語句,但是依然保留了goto作為關鍵字
在java中如果想實現goto一樣跳轉語句的功能可以使用標簽編程
請看如下demo:GotoLabel.java
package javabase.flowcontrol; public class GotoLabel { /** *java標簽編程應用 */ public static void main(String[] args) { int i = 0; outer: //此處不可以寫其它的任何代碼 //System.out.println("outer man!"); for(;true;){ inner: //此處不可以寫其它的任何代碼 //System.out.println("innter man!"); for(;i<10;i++){ System.out.println("i = " + i); if(i == 2){ System.out.println("continue"); continue; } if(i == 3){ System.out.println("break"); i++; break; } if(i == 7){ System.out.println("continue outer"); i++; continue outer; } if(i == 8){ System.out.println("break outer"); break outer; } for(int k = 0; k < 5; k++){ if(k == 3){ System.out.println("continue inner"); continue inner; } } } System.out.println("hello world"); } System.out.println("fuck in java"); } } /*輸出結果: i = 0 continue inner i = 1 continue inner i = 2 continue i = 3 break hello world i = 4 continue inner i = 5 continue inner i = 6 continue inner i = 7 continue outer i = 8 break outer fuck in java */ |
一般的continue會退回最內層循環的開頭,并繼續執行
帶標簽的continue會到達標簽的位置,并重新進入緊接在那個標簽后面的循環
一般的break會中斷并跳出當前的循環體
帶標簽的break會中斷并跳出標簽所指的循環