在 Java 程式中寫下一個數值,則編譯器會為該數值配給一個記憶體空間,然而在程式設計時,您經常會需要先擁有記憶體空間,該空間中要放些什麼數值您事先並無法得知,必須要等程式開始執行並運算之後,才會將運算結果儲存至該空間中。
您可以先宣告一個記憶體空間,告知編譯器這個空間將儲存的資料是什麼型態,並且這個記憶體空間會有個名稱,稍後您執行程式時,可以使用這個名稱,將指定資料存入預先宣告的記憶空間之中,這樣的名稱與空間叫作「變數」( Variable ),而宣告的這個動作稱之為變數宣告。
在方法中進行變數宣告的語法如下:
type identifier = [value];
其中 type 用來宣告變數的資料型態,可使用關鍵字 byte、short、int、long、float、double、boolean 等來宣告,主要看您需要多大的空間來儲存資料。
dentifier 是您要對變數取的名稱,變數的名稱必須能表示出該變數的作用,例如用 ageOfStudent 這樣的名稱來表示,這個變數中儲存的資料是學生的年齡。
=是指定運算子( Assignment operator ),用來將右邊的 value 指定給左邊的變數來儲存。
public class VariableDemo { public static void main(String[] args) { //宣告並指定值 int ageOfStudent = 18; char sexOfStudent = 'M'; // print()方法在顯示文字後不換行 System.out.print("學生年齡: "); System.out.println(ageOfStudent); System.out.print("學生姓別: "); System.out.println(sexOfStudent); //取得變數的值 ageOfStudent = 20; sexOfStudent = 'F'; System.out.print("學生年齡: "); System.out.println(ageOfStudent); System.out.print("學生姓別: "); System.out.println(sexOfStudent); } }程式碼 4-3 VariableDemo.java
注意在第 3 行中,宣告 char 變數在指定值時,字元值必須使用單引號包括,在宣告變數並指定值之後,您可以直接使用變數名稱來取得變數所儲存的值,如第 8 行與第 10 行所示範的,而如果您打算修改變數中所儲存的值,則再使用指定運算子來指定,如第 12 行與 13 行所示範的,不必再重新宣告變數,範例 4-3 的編譯與執行結果如下:
在 Java 中,變數的名稱是有大小寫之分的,也就是說ageOfStudent 與 ageofstudent 這樣的名稱是兩個不同的變數。
您也可以指派一個變數的值給其它變數,右邊變數的值會複製一份給左邊變數,例如以下的程式片段中,age 變數的值會是 ageOfStudent 變數的值,所以程式會在螢幕上顯示 18:
int ageOfStudent = 18; int age = ageOfStudent; // 指定變數給另一個變數 System.out.println(age);
有時候您想要指定一個值給變數,之後不再改變它的內容,目的是為了方便使用名稱來取用某個數值,例如用 PI 這個變數名來取用 3.14159 的值,則您可以在宣告變數時,一併使用 final 關鍵字,例如:
final double PI = 3.14159;
使用 final 關鍵字宣告的變數,在指定值之後就不能改變它的值,如果您試圖改變,則編譯器會告訴您不可以這麼作,舉個例子來說:
final double PI = 3.14159; PI = 3.14; // 試圖改變 final 所宣告的變值之值
如果程式中撰寫了以上的程式片段,則編譯時 就會出現 cannot assign a value to final variable 的錯誤訊息。
重點提示
使用 final 宣告的變數,通常變數名稱會以全部大寫來表示,這可以提醒程式設計人員所使用的變數可能是使用 final 宣告的變數。
宣告變數會使得編譯器提供一塊記憶體空間,供您未來儲存數值,空間被宣告之後,當中可能含有未知的數值,在未指定數值給變數之前,您不可以直接取用變數的值,事實上編譯器也會發生錯誤訊息,例如:
int ageOfStudent; // 宣示變數但不指定值 System.out.println(ageOfStudent); // 顯示變數
上面的程式片段在編譯時將會出現 variable ageOfStudent might not have been initialized 錯誤訊息,您必須在指定值之後才能取用變數,例如:
int ageOfStudent = 18; System.out.println(ageOfStudent);
在宣告變數時必須使用關鍵字 byte、short、int、long、float、double、boolean 等告知編譯器,您將儲存什麼資料型態的資料至變數中,而您在程式中寫下一個字面值時,編譯器會預設它的資料型態,如果在宣告變數並指定值時,這樣寫不會有什麼問題。
int age = 18; double score = 90.5;
因為編譯器會為數值 18 分配 int 型態的記憶體空間,為數值90.5 分配 double 型態的記憶體空間,但如果您這麼宣告的話,編譯器會出現錯誤訊息:
int age = 2036854775808; float score = 90.5;
因為 2036854775808 超過了 int 型態變數所能儲存的範圍,編譯器會出現 integer number too large 的錯誤訊息;90.5 編譯器預設為它提供了 double 型態的空間,而您卻指定這個值給 float 型態的變數,編譯器會出現 possible loss of precision 的錯誤訊息。
當提供的數值其資料型態與變數的資料型態不符時,我們必須考慮數值的晉升( Promotion )與轉型( Casting )問題。
晉升( Promotion )如果變數的資料型態其儲存範圍比指定的數值之資料型態為大時,則會發生數值型態晉升的動作,簡單的說,就是數值的型態會自動提昇為符合變數之資料型態,舉例來說,下面的程式碼會發生晉升的動作:
long money = 10;
10 被指定給 money,由於變數 money 是 long 型態,資料型態自動從 int 變為 long,資料型態晉升動作發生時,編譯器不會有任何的訊息出現。
轉型( Casting )如果數值的資料型態之儲存範圍比變數的資料型態為大時,由於原數值無法將所有的容量儲存至變數中,因而編譯器會提出錯誤訊息,例如:
long money = 10; int smallMoney = money;
在上面的程式片段中,money 儲存了 long 型態的數值(10被晉升為 long 型態),而您將 money 指定給 smallMoney 時,由於 smallMoney 變數的型態是 int,其容量不足以容納 long 型態數值,因而會出現以下的錯誤訊息:
possible loss of precision found : long required: int int smallMoney = money;
如果您確定要將資料型態大的值指定給資料型態小的變轉型數,則您必須明確進行轉型(Casting)的動作,方法是使用括號()包括目標資料型態的關鍵字,例如以下的程式片段就不會有錯誤:
long money = 10; int smallMoney = (int) money;
同樣的方式也適用於 float 與 long 的轉型,例如以下的程式片段是沒有問題的:
double pi = 3.14159; float piAlso = (float) 3.14; // 轉型為 float
當然,轉型會縮小記憶體空間,原來資料有可能會失去某些訊息,例如失去數值上的一些精確度。