Java 變量
本小節(jié)我們將介紹 Java 語言中也是編程語言中的一個(gè)基本概念:變量。
通過本小節(jié)的學(xué)習(xí),你將了解到變量是什么,如何創(chuàng)建變量,如何操作變量,變量的命名規(guī)范,這些是我們本小節(jié)學(xué)習(xí)的重點(diǎn)。我們也會(huì)介紹常量的概念和使用。
1. 什么是變量
在程序設(shè)計(jì)中,變量是指一個(gè)包含值的存儲(chǔ)地址以及對應(yīng)的符號(hào)名稱。
從定義上來看,變量大概可分為兩部分:變量的名字和變量的值,可通過變量名來訪問變量值。簡單來說,變量就是存儲(chǔ)數(shù)據(jù)的載體。
對于 Java 語言來講,Java 是一種強(qiáng)類型的語言,因此變量都必須有一個(gè)類型。在 Java 代碼中,變量是長這個(gè)樣子的:
// =左側(cè)的age是變量名,右側(cè)的22是變量值
int age = 22;
2. 創(chuàng)建變量
我們已經(jīng)在上面看到了變量在代碼中的樣子,現(xiàn)在我們來動(dòng)手創(chuàng)建變量。
在Java
語言中,我們需要做兩件事才能創(chuàng)建一個(gè)變量:
- 給變量起一個(gè)名字
- 定義變量的數(shù)據(jù)類型
創(chuàng)建變量的過程也叫聲明變量,聲明變量的語法如下:
DataType 變量名;
Tips:關(guān)于數(shù)據(jù)類型,我們將在下一小節(jié)介紹。此處只需知道變量有類型之分即可。
聲明一個(gè)變量,實(shí)例如下:
int a;
上述代碼,聲明了一個(gè)名字為a
,類型為整型的變量。
我們可以再聲明一個(gè)名字為b
,類型為字符型的變量,實(shí)例如下:
char b;
再聲明兩個(gè)整型的變量age
、number
,實(shí)例如下:
int age;
int number;
3. 給變量賦值
變量聲明操作已經(jīng)告訴了編譯器變量的數(shù)據(jù)類型。數(shù)據(jù)類型決定了變量中可以存放什么,不能存放什么,上述的變量a
為int
類型(整型),因此只能存放整數(shù)。
一旦聲明了一個(gè)變量,我們就可以使用賦值語句為其賦值,實(shí)例如下:
// 變量聲明語句
int a;
// 賦值語句
a = 1;
為變量分配值的語句,就稱為賦值語句。需要特別提醒的是,語句中=
的意義不同于數(shù)學(xué)中的等號(hào),在 Java 中,=
是賦值符號(hào)。
對于變量的聲明和賦值操作,我們也可以將這兩條語句合并成一條語句,實(shí)例如下:
int a = 1;
另外,如果要?jiǎng)?chuàng)建多個(gè)類型相同的變量,我們可以在一條語句中將多個(gè)變量的聲明進(jìn)行分組:
int a, b;
a = 1;
b = 2;
為了精簡語法,還可以將變量的聲明和賦值同時(shí)分組:
int a = 1, b = 2;
在作用域范圍內(nèi),變量的值能夠隨時(shí)訪問或重新賦值,比如:
class PrintVariable {
public static void main(String[] args) {
int a = 20;
System.out.println("修改前變量a=" + a);
// 將變量a重新賦值為100
a = 100;
System.out.println("修改后變量a=" + a);
}
}
運(yùn)行結(jié)果:
修改前變量a=20
修改后變量a=100
上述代碼中,聲明了一個(gè)整型變量a
,且初始化值為20
,可以使用a = 100;
這種賦值語句,對變量a
重新賦值。
注意,在 Java 中,對變量進(jìn)行重新賦值,這樣的寫法是錯(cuò)誤的:
int a = 20;
int a = 100;
編譯代碼,將會(huì)拋出異常:
Test.java:5: 錯(cuò)誤: 已在方法 main(String[])中定義了變量 a
int a = 2;
^
1 個(gè)錯(cuò)誤
編譯報(bào)錯(cuò)的原因很簡單,第二行代碼再次定義了變量a
,而變量a
已經(jīng)在內(nèi)存中存在了,不能再重復(fù)定義。這與對變量重新賦值不同。
4. 變量命名規(guī)范
對于變量的命名,每種編程語言都有自己的規(guī)則和約定,Java 語言也不例外。命名變量的規(guī)則和約定如下:
- 變量的名稱可以是任何合法的標(biāo)識(shí)符,以字母,美元符號(hào)
$
或下劃線_
開頭。但是,按照約定俗成,變量應(yīng)始終以字母開頭,不推薦使用美元符號(hào)和下劃線開頭; - 開頭后續(xù)的字符可以是字母、數(shù)字、美元符號(hào)或下劃線。為變量選擇名稱時(shí),推薦使用完整的英文單詞,不推薦使用單詞縮寫,更不要使用中文拼音。這樣做有利于代碼的閱讀和理解。另外請牢記,選擇的名稱不能是關(guān)鍵字或保留字;
- 變量命名區(qū)分大小寫;
- 變量命名應(yīng)采用小駝峰命名法。所謂小駝峰命名法,就是如果你選擇的名稱只包含一個(gè)單詞,那么用全部小寫字母拼寫該單詞;如果名稱包含多個(gè)單詞,請將第二個(gè)單詞起的每個(gè)單詞的第一個(gè)字母都大寫;
- 如果變量存儲(chǔ)了一個(gè)常量值,要將每個(gè)字母大寫并用下劃線字符分隔每個(gè)單詞。比如
static final int MAX_NUM = 100
。按照約定俗成,除了常量命名的情況,下劃線字符永遠(yuǎn)不會(huì)在其他地方使用。
下面我們對照上述規(guī)則和約定來看幾個(gè)實(shí)例。
實(shí)例1:
int $a;
int _b;
int age;
上面3個(gè)變量的聲明都是合法的,但是根據(jù)約定俗稱,不推薦$a
這種以美元符號(hào)開頭、_b
這種以下劃線開頭的命名方式。
實(shí)例2:
public class VariablesNameing2 {
public static void main(String[] args) {
String Name = "Colorful";
String name = "Colorful1";
System.out.println("Name=" + Name);
System.out.println("name=" + name);
}
}
變量名區(qū)分大小寫,因此上面的Name
和name
是兩個(gè)不同的變量。由于只有一個(gè)單詞組成,應(yīng)將單詞使用全部小寫拼寫,不推薦第1行Name
這種命名方式。
實(shí)例3:
// 聲明姓和名變量
String firstName;
String lastname;
上面聲明了兩個(gè)變量 firstName
和lastname
,由于它們都是由兩個(gè)單詞組成,按照小駝峰命名法的約定俗成:第2行lastname
變量名由兩個(gè)英文單詞組成,因此推薦改為lastName
。
5. 常量
所謂常量,就是恒常不變的量。我們可以將常量理解成一種特殊的變量。
與變量不同的是,一旦它被賦值后,在程序的運(yùn)行過程中不允許被改變。常量使用final
關(guān)鍵字修飾:
final DataType 常量名 = 常量值;
Tips:常量的命名規(guī)范與普通變量有所不同,要將每個(gè)字母大寫并用下劃線字符分隔每個(gè)單詞。
如果我們嘗試在代碼中修改常量的值:
class ConstantTest {
public static void main(String[] args) {
// 聲明并初始化常量 TOTAL_NUM
final int TOTAL_NUM = 200;
// 對 TOTAL_NUM 重新賦值
TOTAL_NUM = 20;
}
}
編譯執(zhí)行代碼,編譯器將會(huì)報(bào)錯(cuò):
ConstantTest.java:6: 錯(cuò)誤: 無法為最終變量TOTAL_NUM分配值
TOTAL_NUM = 20;
^
1 個(gè)錯(cuò)誤
適當(dāng)?shù)厥褂贸A靠梢蕴岣叽a的安全性和可維護(hù)性。例如,我們可以在程序中聲明一個(gè)表示網(wǎng)站名稱的常量: final String SITE_NAME = "慕課網(wǎng)";
,這樣在所有需要用到網(wǎng)站名稱的地方,都調(diào)用這個(gè)常量即可。這樣既保證了其值不可修改,提高了代碼的安全性,又統(tǒng)一了調(diào)用方的規(guī)范。
6. 變量的種類
學(xué)習(xí)變量的種類,需要你對 Java 的類和對象有一定的了解。目前不要求完全理解,等到后面學(xué)完面向?qū)ο笙嚓P(guān)知識(shí)后再回過頭來回味。
Java 語言定義了以下4 種變量 :
- 實(shí)例變量(見代碼中
instanceVariable
) - 類變量(見代碼中
classVariable
) - 局部變量(見代碼中
localVariable
) - 參數(shù)(見代碼中
parameter
和args
)
public class KindsOfVariables {
// 1.實(shí)例變量
public int instanceVariable = 1;
// 2.類變量
public static int classVariable;
public void demoMethod(int parameter) { // 3.參數(shù)
// 4.局部變量
int localVariable;
}
public static void main(String[] args) {
// 入口方法
}
}
6.1 實(shí)例變量
實(shí)例變量在類范圍內(nèi)聲明。聲明時(shí)不使用static
關(guān)鍵字修飾,因此也稱為非靜態(tài)字段。
實(shí)例變量用于存儲(chǔ)對象的狀態(tài),它的值對于類的每個(gè)實(shí)例都是唯一的,每個(gè)對象都擁有自己的變量副本。只要相應(yīng)的對象存在于內(nèi)存中,它就占用著存儲(chǔ)空間。
下面是一個(gè)實(shí)例變量的實(shí)例,當(dāng)然,我們還沒有介紹類和對象的概念,如果你了解類和對象,可以閱讀源碼幫助理解:
public class Student {
// 實(shí)例變量 name
public String name;
// 實(shí)例變量 age
public int age;
// 構(gòu)造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 打印學(xué)生基本信息的方法
public void printInfo() {
System.out.println("學(xué)生姓名為:" + name);
System.out.println("學(xué)生年齡為:" + age);
}
public static void main(String[] args) {
// 實(shí)例化兩個(gè)學(xué)生對象
Student student1 = new Student("小慕", 20);
Student student2 = new Student("小李", 18);
// 分別調(diào)用打印學(xué)生基本信息方法,打印兩個(gè)對象下的兩個(gè)實(shí)例變量
student1.printInfo();
System.out.println("--------分割線--------");
student2.printInfo();
}
}
運(yùn)行結(jié)果:
學(xué)生姓名為:小慕
學(xué)生年齡為:20
--------分割線--------
學(xué)生姓名為:小李
學(xué)生年齡為:18
實(shí)例變量和實(shí)例對象相關(guān),因此需要通過new
關(guān)鍵字實(shí)例化出對象,通過對象才能訪問其實(shí)例變量(也稱實(shí)例屬性)。 上述代碼中,name
和age
就是用于存儲(chǔ)其對象的屬性,我們實(shí)例化了兩個(gè)學(xué)生對象,其實(shí)例變量name
和age
,在每個(gè)對象實(shí)例中是唯一的。
6.2 類變量
類變量在類范圍內(nèi)使用static
關(guān)鍵字修飾,因此類變量又被稱為靜態(tài)字段、靜態(tài)變量。
static
修飾符告訴編譯器,無論類被實(shí)例化多少次,類變量始終只有一個(gè)變量副本。只要類被加載到內(nèi)存中,它就會(huì)存在。
另外,類變量可以被聲明為常量,通過使用final
關(guān)鍵字以表示變量永遠(yuǎn)不會(huì)改變。例如:public static final NAME = "慕慕"
,這里的NAME
就是不會(huì)改變的常量。再次提醒,在常量的命名規(guī)范中,要將字母全部大寫。
對于類變量,我們再來看一個(gè)實(shí)例:
public class Course {
// 類變量 courseType
public static String courseType = "文字課程";
// 常量 COURSE_NAME
public static final String COURSE_NAME = "Java 基礎(chǔ)教程";
public static void main(String[] args) {
// 分別打印類變量和常量
System.out.println(Course.courseType);
System.out.println(Course.COURSE_NAME);
}
}
運(yùn)行結(jié)果:
文字課程
Java 基礎(chǔ)教程
類變量和類相關(guān),因此不需要使用new
關(guān)鍵字實(shí)例化對象后再調(diào)用,可以直接通過類名 + .
點(diǎn)運(yùn)算符 + 類變量名的方式調(diào)用。
上述代碼中,courseType
和COURSE_NAME
都使用static
關(guān)鍵字修飾,它們都可以直接通過Course.變量名
的方式調(diào)用。
6.3 局部變量
局部變量是在方法范圍內(nèi)被聲明和使用的。它們沒有任何關(guān)鍵字修飾,可以根據(jù)變量聲明的位置來認(rèn)定局部變量(即方法的左花括號(hào)和右花括號(hào)之間),因此,局部變量只可以對聲明它們的方法可見。方法返回后,它們將被銷毀。
在main
方法中的局部變量實(shí)例:
public static void main(String[] args) {
// 局部變量 name
String name = "小慕";
// 局部變量 age
int age = 20;
System.out.println("姓名:" + name);
System.out.println("年齡:" + age);
}
我們再來看一個(gè)自定義方法中的局部變量實(shí)例:
public class PrintNumber {
public void printer() {
int num = 10;
for(int i = 1; i <= num; i ++) {
System.out.println(i);
}
}
}
局部變量和方法相關(guān),因此只能在方法內(nèi)部局部定義和使用,在第二個(gè)實(shí)例中沒有代碼注釋,請思考printer
方法中有哪幾個(gè)局部變量。
6.4 參數(shù)
參數(shù)是用于傳遞給方法簽名的變量(例如入口方法main
中的args
),它們可以在方法中的任何位置被調(diào)用。在方法執(zhí)行的期間位于內(nèi)存中,方法返回后被銷毀。
例如,上面實(shí)例變量的實(shí)例中,Student
類的構(gòu)造方法就接收兩個(gè)參數(shù),如下為代碼截取:
// Student 類構(gòu)造方法
public Student(String name, int age) { // name 和 age 就是傳遞給Student構(gòu)造方法的參數(shù)
this.name = name;
this.age = age;
}
注意,方法體中的this.name
和this.age
指代的是實(shí)例變量,而 name
和age
是參數(shù),它們被用于賦值給實(shí)例變量。
7. 小結(jié)
在本小節(jié)中,我們知道了變量是存儲(chǔ)數(shù)據(jù)的載體,聲明變量時(shí)要注意變量的命名規(guī)范,給變量賦值時(shí)要根據(jù)聲明的數(shù)據(jù)類型賦值。
Java 中變量有4個(gè)種類,分別是:實(shí)例變量、類變量、局部變量、參數(shù)。其中變量如果使用了final
關(guān)鍵字修飾,就可定義一個(gè)不可變的常量。
當(dāng)然,需要再次強(qiáng)調(diào)的是:不要使用中文拼音來命名變量,這是很常見的但非常不好的習(xí)慣。英文基礎(chǔ)差的童鞋可以下載一個(gè)英文詞典,當(dāng)你要選擇一個(gè)變量的名稱時(shí),多查閱一下單詞,選擇出最符合變量特征的單詞。好的變量命名不僅讓你的代碼易于閱讀理解,也有助于你更好地梳理實(shí)際編碼中繁瑣的業(yè)務(wù)邏輯。