G筆記_Java基礎(變數、基本型別、運算子和表示式-1)[案例]
JAVA Fundamental DAY02
1 變數使用常用錯誤彙總
1.1 問題
在我們使用變數的過程中,會遇到一些問題,在此將這些問題進行彙總,在今後使用的過程中,避免出錯。即使出現錯誤也可以很快的找到問題所在。
1.2 方案
變數在使用的過程中,常見問題總結為如下幾點:
1) 使用未經宣告的變數。
2) 使用不符合Java識別符號命名規則的變數。
3) 使用未經初始化的變數。
4) 變數的賦值與變數的型別不匹配
1.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:使用未經宣告的變數
Java語言語法規定,變數使用之前必須宣告,否則會有編譯錯誤。大多數時候我們都記得這個規範,但是還是會出現變數未宣告就使用的情況,請看如下程式碼:
- public static void main(String[] args) {
- a = 1; // 編譯錯誤,變數沒有宣告
- int score = 0;
- scord = 100; // 編譯錯誤
- System.out.println(score);
- }
編譯上述程式碼,會發現在程式碼“a=1;”處和程式碼“scord=100;”處出現編譯錯誤。出現編譯錯誤的原因是變數a和變數scord沒有被宣告。變數的宣告包含兩點:變數的型別和變數的名稱。a變數沒有被宣告的原因是沒有變數的型別。scord變數沒有被宣告的原因也是因為沒有變數型別,但是檢視程式碼scord=100;的上下行的程式碼會發現聲明瞭score變數,分析這三行程式碼,scord=100行出現編譯錯誤的原因是變數沒有被宣告,沒有宣告的原因是變數score拼寫成了scord。
步驟二:使用不符合Java識別符號命名規則的變數
Java中的變數的命名必須符合Java識別符號的規則:
1) 可以以字母、數字、“_”和“$”符組成;
2) 首字元不能以數字開頭;
3) 中文可以作為變數名,但不提倡使用;
4) Java大小寫敏感,命名變數時需要注意;
5) 不能使用Java保留字(一些Java語言規定好的,有特殊含義的字元),如:int、if、for、break等。
下面的程式碼體現了Java變數的命名規則:
- int 123go = 100; // 編譯錯誤,不能以數字開頭。
- int 成績 = 60;// 編譯沒錯,但不建議使用。
- int break= 200; // 編譯錯誤,break是Java保留字。
- int score = 80;
- System.out.println(Score);
- // 編譯錯誤,Java大小寫敏感,Score變數沒有宣告。
上述程式碼中,分別有如下錯誤:
1) 變數“123go”不符合Java的命名規範,原因是變數名不能以數字開頭;
2) 變數“成績“編譯時是正確的,但是這種使用漢字進行命名的方式不建議使用;
3) 變數”break“處會出現編譯錯誤,原因是break是Java的保留字,不能作為變數名;
4) 在輸出變數”Score“處會出現編譯錯誤,原因是變數名是大小寫敏感的。int score=80;處宣告的變數和下一行程式碼中輸出的Score是兩個變數,所以變數Score沒有宣告。Java語言語法規定,變數使用之前必須宣告,否則會有編譯錯誤。
另外,Java 變數名的定義應“見名知意”;同時,Java程式設計規範要求:變數的命名需採用“駝峰命名法”,即如果變數的名字由多個單片語成,除第一個單詞外,其他單詞的首字母大寫,其餘的字母小寫,例如:salary、 empNo studentName 等。
步驟三:使用未經初始化的變數
Java語言規定變數在使用之前必須初始化,即必須給該變數賦予特定的值。請看下列程式碼:
- public static void main(String[] args) {
- int a, b = 10;
- int c = a + b; // 編譯錯誤,變數a沒有初始化
- System.out.println(c);
- }
在上述程式碼中,程式碼行int c = a + b;處會出現編譯錯誤,因為此行程式碼使用到了變數a,但是該變數卻沒有被初始化。
另外,有些語句結構(如if、for等)需要條件滿足時才會執行;Java編譯器不認為在這些語句塊中的賦值語句可以實現初始化操作。檢視如下程式碼:
- int sum;
- int a = 20;
- int b = 10;
- if(a>0) {
- sum = 0; // 當a大於0的時候,該語句才會執行。
- sum = a + b;
- }
- System.out.println(sum); // 編譯錯誤,編譯器認為sum沒有初始化。
上述程式碼中,語句System.out.println(sum);處會出現編譯錯誤,Java編譯器不認為放在if語句塊中的sum=0;可以實現初始化操作。
步驟四:變數的賦值與變數的型別不匹配
變數在宣告時指定了型別,Java編譯器會檢測對該變數的操作是否與其型別匹配,如果對變數的賦值或者操作與其型別不匹配,會產生編譯錯誤。
- public static void main(String[] args) {
- int salary;
- salary = 15000.50; // 編譯錯誤,整型變數不可以賦予浮點值(小數)。
- }
上述程式碼中,變數salary宣告時的型別為int,後續賦值為15000.50,而15000.50是浮點型別,因此導致編譯錯誤。整數型別變數不可以賦予浮點型別的值。
1.4 完整程式碼
本案例是總結性的知識,沒有完整的程式碼。
2 整數型別(int、long)使用常見問題彙總
2.1 問題
在我們使用整數型別的過程中,會遇到一些問題,在此將這些問題進行彙總,在今後使用的過程中,避免出錯。即使出現錯誤也可以很快的找到問題所在。
2.2 方案
整數型別在使用的過程中,常見的問題有以下幾點:
1) 整數直接量超出了整數的範圍。
2) 關於整數的除法:兩個整數相除,會捨棄小數的部分,結果也是整數。
3) 整數運算的溢位:兩個整數進行運算時,其結果可能會超過整數的範圍而溢位。
4) 表示long直接量,需要以 L 或 l 結尾。
2.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:整數直接量超出了整數的範圍
int是最常用的整數型別。一個int型別的變數佔用4個位元組(32位),最大表示範圍為:-2^31 ~ 2^31-1,即 -2147483648 ~2147483647。
整數直接量(literal), 即直接寫出的整數。整數的直接量的型別預設為int型別,如果直接寫出的整數超過了int的表達範圍,將會出現編譯錯誤。請看如下程式碼:
- int d = 10000000000;
以上程式碼中,10000000000不屬於int型別的直接量,因為Java認為所有直接寫出的整數都是int型別,而這個數值超過了int的表達範圍。
步驟二:關於整數的除法
在Java中,兩個整數相除,會捨棄小數的部分,結果也是整數。請看如下程式碼:
- int c = 5/3;
- System.out.println(c); // c的值為1
在上述程式碼中,執行後,c的值為1。說明兩個整數相除,捨棄了小數部分,只保留了整數部分。
步驟三:整數運算的溢位
兩個整數進行運算時,其結果可能會超過整數的範圍而溢位,請看如下程式碼:
- int a = 2147483647;
- int b = -2147483648;
- a = a + 1;
- b = b - 1;
- System.out.println("a=" + a);
- System.out.println("b=" + b);
上述程式碼執行後的輸出結果為:
- a=-2147483648
- b=2147483647
變數a最初的值為2147483647,是int型別的最大值,加1以後出現了溢位現象,a的值變成了int型別的最小值。而b變數最初賦的值為-2147483648,是int型別的最小值,減1以後出現了溢位現象,b的值變成了int型別的最大值。這顯然不符合加法和減法的規則,所以,在今後使用的時候要注意類似的問題。
步驟四:表示long直接量,需要以 L 或 l 結尾
在表示整數時,如果int型別的範圍不夠,可以使用long型,一個long型的變數佔用8個位元組(64位),最大表示範圍為:-2^63 ~ 2^63-1,即 -9223372036854775808 ~ 9223372036854775807。當一個直接量超過int型別的最大值時,那要用long型別來表示,如果要表示long直接量,需要以 L 或 l 結尾。請看下列程式碼:
- long a = 10000000000; // 會有編譯錯誤
- long b = 10000000000L;
上述程式碼中,10000000000超過了int型別的最大值,把它直接賦值給long型別會出現編譯錯誤。需要像變數b那樣在10000000000後邊加L。
2.4 完整程式碼
本案例是總結性的知識,沒有完整的程式碼。
3 浮點型別(float、double)使用常見問題彙總
3.1 問題
在我們使用浮點型別的過程中,會遇到一些問題,在此將這些問題進行彙總,在今後使用的過程中,避免出錯。即使出現錯誤也可以很快的找到問題所在。
3.2 方案
浮點型別在使用的過程中,常見的問題有以下幾點:
1) 浮點數的直接量為double型別。
2) 浮點數存在舍入誤差問題。
3.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:浮點數的直接量為double型別
浮點數,就是小數,包括: float和double。預設的浮點直接量為double型,如果需要表示float型別的直接量,需要加“f”或“F”字尾。請看如下程式碼:
- float f1 = 3.14 ;
以上程式碼,會出現編譯錯誤。3.14是double型別的直接量,如果表示float型別的直接量應該寫成3.14f。
步驟二:浮點數存在舍入誤差問題
由於浮點數內部用二進位制的方式來表示十進位制,會存在舍入誤差。二進位制系統中無法精確的表示1/10,就好像十進位制系統中無法精確的表示1/3一樣。對於一些要求精確運算的場合會導致程式碼的缺陷。請看如下程式碼:
- double money = 3.0;
- double price = 2.9;
- System.out.println(money - price);
上述程式碼的輸出結果為:
- 0.10000000000000009
檢視上述結果,並沒有如我們想象的為0.1。如果需要精確的運算可以考慮放棄使用double或float而採用BigDecimal 類來實現。關於這一點,將在後續的章節中介紹。
3.4 完整程式碼
本案例是總結性的知識,沒有完整的程式碼。
4 對char型別變數的各種賦值方式彙總
4.1 問題
在我們使用char型別的過程中,會遇到一些問題,在此將這些問題進行彙總,使今後使用的過程中,不出錯。即使出現錯誤也可以很快的找到問題所在。
4.2 方案
char型別在使用的過程中,常見的問題有以下幾點:
1) 字元型別儲存中文。
2) char型別的值可以作為整數型別直接使用。
4.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:字元型別儲存中文
char型別是否可以儲存中文?答案是肯定的。字元型別事實上是一個16位無符號整數,這個值是對應字元的編碼, Java字元型別採用Unicode字符集編碼。Unicode是世界通用的定長字符集,所有的字元都是16位字元直接量。對於中文,可以採用諸如: ‘中’ 的形式,也可以採用其對應的16進位制的表示形式,例如: ‘\u4e2d’。
步驟二:整數型別和char型別的關係
char型別的值可以直接作為整數型別的值來使用,字元型別事實上是一個16位無符號整數,即全部是正數,表示範圍是0~65535。請看如下程式碼:
- char zhong='瘋';
- int zhongValue=zhong;
- System.out.println(zhongValue);
上述程式碼的輸出結果為:
- 30127
上述輸出結果為0~65535範圍的。
另外,如果把0~65535範圍內的一個int整數賦給char型別變數,系統會自動把這個int型別整數當成char型別來處理。請看如下程式碼:
- char c=97;
- System.out.println(c);
上述程式碼的輸出結果為a。這說明系統自動把整數型別97當成char型別來處理,處理的結果為a,即,97為字母a的unicode碼。
4.4 完整程式碼
本案例是總結性的知識,沒有完整的程式碼。
5 型別轉換常見問題彙總
5.1 問題
在我們資料型別轉換的過程中,會遇到一些問題,在此將這些問題進行彙總,使今後使用的過程中,不出錯。即使出現錯誤也可以很快的找到問題所在。
5.2 方案
資料型別轉換在使用的過程中,常見的問題有以下幾點:
1) 強制轉換時的精度喪失和溢位。
2) 數值運算時的自動轉換。
3) byte、char、short轉換為int的問題。
5.3 步驟
實現此案例需要按照如下步驟進行。
步驟一:強制轉換時的精度喪失和溢位
基本型別之間的相互轉換,需要注意的是,強制轉換時可能會造成精度的喪失和溢位,請看如下程式碼:
- long l = 1024L * 1024 * 1024 * 4;
- int j = (int) l; // 會產生溢位
- System.out.println(j); // 結果為:0
上述程式碼輸出的結果為0,是因為在將long型別變數l轉換為int型別變數j的時候產生了溢位。
另外,請看如下精度喪失的例子:
- double pi = 3.141592653589793;
- float f = (float) pi; // 會造出精度的損失
- System.out.println(f); // 結果為:3.1415927
上述程式碼的輸出結果為3.1415927,值保留了7位小數,這是因為將double型別的變數pi轉換為float型別的變數f時造成了精度的損失。
步驟二:數值運算時的自動轉換
多種基本型別參與的表示式運算中,運算結果會自動的向較大的型別進行轉化。請看如下示例:
- long distance = 10000 * 365 * 24 * 60 * 60 * 299792458L;
上述程式碼中,有int型別資料和long型別資料,由於有long型的直接量299792458L參與,整個表示式的結果為long。
- double change = 800 - 599.0;
上述程式碼中,由於有double型的直接量599.0參與,整個表示式的結果為 double。
- double persent1 = 80/ 100;
上述程式碼中,結果為0.0。右邊都是int型資料,語法運算後的結果也為int型別,結果為0,再賦值給double型,將0轉化為 0.0。請對比下面的程式碼:
- double persent2 = 80.0/ 100;
上述程式碼中,結果為0.8,右邊表示式有double型直接量參與,運算結果為double型。
步驟三:byte、char、short轉換為int的問題
byte、char、short 三種類型實際儲存的資料都是整數,在實際使用中遵循如下規則:
1) int直接量可以直接賦值給byte、char和short,只要不超過其表示範圍。
2) byte、char、short三種類型參與運算時,先一律轉換成int型別再進行運算。請看如下示例程式碼:
- byte b1=28;
- byte b2=20;
- byte b3=b1+b2;
上述程式碼在第三行會出現編譯錯誤,原因是b1+b2的結果為int型別。改變上述程式碼如下:
- byte b1=28;
- byte b2=20;
- int b3=b1+b2;
檢視上述程式碼,會發現不會再出現編譯錯誤。char型別、short型別和byte型別是相似的。
5.4 完整程式碼
本案例是總結性的知識,沒有完整的程式碼。
6 年齡判斷程式
6.1 問題
本案例需要使用互動的方式判斷年齡的範圍:使用者從控制檯輸入一個年齡,由程式判斷該年齡是否在18~50之間。程式互動過程如圖-1所示:
圖- 1
6.2 步驟
實現此案例需要按照如下步驟進行。
步驟一:定義類及 main方法
首先定義一個名為 Age的類,並在類中新增Java應用程式的主方法main,程式碼如下所示:
- public class Age {
- public static void main(String[] args) {
- }
- }
步驟二:讀取控制檯輸入
在main方法中,例項化Scanner類,並呼叫Scanner類的nextInt() 方法接收使用者從控制檯輸入的年齡,使用完畢後將scanner物件關閉,以釋放資源。程式碼如下所示:
- import java.util.Scanner;
- public class Age {
- public static void main(String[] args) {
- Scanner scanner = new Scanner(System.in);
- System.out.println("請輸入年齡:");
- int age = scanner.nextInt();
- scanner.close();
- }
- }
在此需要注意匯入Scanner類所在的包。
步驟三:判斷年齡所在的範圍
接收到年齡後,判斷年齡是否在18~50之間。如果輸出結果為true,則說明年齡在18~50之間,否則,年齡不在18~50之間,程式碼如下所示:
- import java.util.Scanner;
- public class Age {
- public static void main(String[] args) {
- Scanner scanner = new Scanner(System.in);
- System.out.println("請輸入年齡:");
- int age = scanner.nextInt();
- System.out.println(age >= 18 && age <= 50);
- }
- }
在上述程式碼中,使用了“&&”邏輯運算子來連線兩個條件。年齡在18~50之間,即,年齡大於等於18且年齡小於等於50,因此需要使用“&&”運算子。
6.3 完整程式碼
本案例的完整程式碼如下所示: