一: 自曾自減原理
class VarDemo { public static void main(String[] args) { int x = 30; x = x++; System.out.println(x); } }
結果: 30
內存中計算實現的過程
temp = x => temp =30
x = x + 1 => x = 31
x = temp => x =30
注: 第一步編譯器發現是 x++;所以會把x先轉到temp臨時內存中,然後x++實現了x=31, 然後將x++賦值給x, x=temp
換成
x = ++x
內存中實現過程是:
x= x + 1 x => 31
x = x x => 31
二: 自動轉換數據類型和強制轉換類型
byte x = 30;
x = x +4;
以上會報錯,解釋:
第一步:
byte x =30;實現的過程是,將int型的30賦值給byte類型的時候,java編譯器底層會做,強制轉換,(如果int型的整數能放入byte類型的話)將30轉換成爲byte類型(否則報錯),在賦值給byte類型的變量x。
第二步:
x是byte類型 + int類型的4,因爲x是變量,底層無法判斷x+4是否能正確的轉換到byte類型,所以報錯
E:\java3200\day002>javac VarDemo2.java
VarDemo2.java:4: 錯誤: 可能損失精度
x = x +4;
^
需要: byte
找到: int
1 個錯誤
但可以強制進行轉換:
x = (byte)(x +4);
三:x+=5; 是否等於 x = x+5
解答:
byte x = 30;
x+=5;
以上不會報錯,以上只有賦值一個步驟。
byte x = 30;
x = x +5;
這個會報錯,報錯的原因就是第二種情況,類型自動轉換不了!以上有先計算x+5 在賦值的兩個步驟
四: 雙與和單與的區別(java中)
&&
&
兩種的區別是,邏輯運算的結果一樣,但是過程不一樣
&& 當左邊的執行結果爲false的時候,右邊不參加運算
& 無論左邊爲何結果,右邊都會運算
綜合以上,&&的效率更高,但是有時候要得到與結果,接右邊一定要參加運算的情況,要使用單與
單與還有一個作用在位運算(6&3)結果 2
0000-0000 0000-0000 0000-0000 0000-0010
五: 兩個變量的交換
兩個變量之間數值的交換
如:
a = 5
b = 9
方法一:採用第三個臨時變量
t = a
a = b
b = t
開發的時候,是使用這種方法,因爲閱讀性強,且臨時空間的開闢不會對性能造成很大的影響!
方法二:不採用第三個臨時變量
a = a + b
b = a -b
a = a - b
這種方法: 可能回超出int型的取值範圍,會強制轉換,數據就會變。且閱讀性差,常用於面試題
方法三: 異或的方法
a = a ^ b ; a = 5 ^ 9
b = a ^ b ; b = (5 ^ 9)^9
a = a ^ b ; a = (5^9)^5
原理: 就是一個數異或一個兩次,還是原來的值
六:三目運算的應用
//獲取兩個數的最大數
max = a>b?a:b
//獲取三個數的最大值
int temp = o>p?o:p
int max = temp>q?temp:q
七:一條語句的代碼塊可以省略{},在流程控制中,什麼叫一條語句呢?
if (score >=90) { if (score >=95) { System.out.println("very very good"); } }
可以省略成:
if (score >=90) if (score >=95) System.out.println("very very good");
因爲: 相對if(score >90) 而言
if (score >=95) System.out.println("very very good");
是一個條件語句。
相對if (score >90)而言
System.out.println("very very good");
是一條語句
八:代碼塊的用途:
{ int a=1; a=a+1; //代碼塊內的運算,可以定義變量的生命週期,作用域值只在這個代碼塊內 System.out.println(a); }
代碼塊可以優化性能,將一些運算放置在代碼塊內,可以節省內存空間,因爲代碼塊內的變量,運算結束後就消失,被回收。作用範圍決定的。 JVM內存有限,代碼劣質可能會造成內存溢出。
九:Switch中的執行過程和順序
不常規的寫法,分析過程
class SwitchDemo { public static void main(String[] args) { int x =4; switch (x) { default: System.out.println("d"); // break; case 1: System.out.println("a"); // break; case 2: System.out.println("b"); break; case 3: System.out.println("c"); break; } } }
執行結果是:
d
a
b
原因:
case 和default兩個無序,在內存中一定是先執行case,在執行defaul。x=4 先執行case 不配 1 2 3
所以執行default,打印輸出"d",因爲沒有break跳出switch,所以往下執行,因爲已經匹配了default,就不用再去判斷是否匹配case中的表達式,所以打印"a", "b",然後遇到break,跳出循環。
注意: 默認的靠近下面花括號的那個case或者default可以省略break的,這樣即使都不寫break也不會死循環,保證了一定存在break
十: while和for的區別
共同點,都是循環,while等做的for也能做,for能實現的,while也能實現,但是兩者還是有區別的。
看以下代碼,執行會出錯
int x =1;
while(x<3) {
System.out.println("x="+x);
x++;
}
System.out.println(x);
for(int y=1;y<3;y++) {
System.out.println("y="+y);
}
System.out.println(y);
原因: for語句中的變量作用域只在for語句中,當for循環完畢後,所有變量都在內存中被銷燬。所以只針對循環而言,for的循環對程序節省內存開銷。
十一: 強類型和弱類型語言的區別
如: 強類型語言java C,數據類型都是分的比較細的,如整數分 byte short int long,任何數據都要定義類型。
如:弱類型語言python 對數據類型就沒那麼細微,整數就是整數類型,且定義變量不需要聲明類型
函數方面的區別(java ,python)對比
java 中函數可以嵌套調用,但是不能嵌套定義,如mian主函數中,不能定義其他函數,只能調用其他函數,因爲java中的函數都是在類當中的,所以函數之間只能存在"兄弟"級別。
python中函數可以嵌套定義,如裝飾器中
java中即使是一個函數,也要定義返回的數據類型,即定義函數的時候,指定這函數的類型,即使沒有函數沒有返回值,也要定義函數的類型爲void類型(不帶返回值的類型),main主函數就是一個void函數類型。
python中return就可以返回任何數據類型了,函數定義不需要指明類型
十二: 函數(方法)的重載
重載:
1.同一個類中
2.函數名相同
3.參數個數不同,或者參數類型不同
4.與返回值類型無關
5.java是嚴謹性的語言,如果存在調用異常,會編譯失敗
重載的實現:
java編譯器會通過參數的不同,選擇調用不同的函數(函數名相同的)
重載的優點:
方法重載可以讓程序更清晰易讀。執行密切相關任務的方法應該使用相同的名字。
如:
public static int add(int a, int b) {
return a +b;
}
public static double add(double a, double b) {
return a+b;