都說(shuō)變量有七八種,到底誰(shuí)是 Java 的親兒子
變量是我們經(jīng)常用到的一種,我在剛學(xué) Java 的時(shí)候,也經(jīng)常被各種變量的概念折磨,當(dāng)時(shí)并沒(méi)有細(xì)摳,但是我在寫一篇類似的文章中,想把變量作為一種小標(biāo)題來(lái)簡(jiǎn)述一下,但是發(fā)現(xiàn),變量這個(gè)概念還是比較繁瑣的,本篇文章就來(lái)深入認(rèn)識(shí)一下 Java 中這些變量的概念。
變量匯總
所以,到底有哪些變量的概念呢?距今為止,目前已知的變量主要有:
- 實(shí)例變量
- 全局變量
- 靜態(tài)變量
- 類變量
- 局部變量
- 成員變量
- 常量
下面我們就采用各個(gè)擊破的方式來(lái)認(rèn)識(shí)每個(gè)概念。
實(shí)例變量
實(shí)例變量又被稱為Instance variables。不使用 static 關(guān)鍵字定義,并且在任何方法、構(gòu)造方法、塊之外的變量都是實(shí)例變量。實(shí)例變量都是基于特定實(shí)例的,實(shí)例變量不會(huì)在實(shí)例之間共享,也就是說(shuō),每一個(gè)對(duì)象的實(shí)例都有自己的一個(gè)實(shí)例變量。下面是實(shí)例變量的一個(gè)例子
- class Fruits {
- public String fruitName; // 具有公共訪問(wèn)權(quán)限的 fruitName;
- private int fruitNum; // 具有私有訪問(wèn)權(quán)限的 fruitNum;
- }
你可以使用下面這種方式進(jìn)行實(shí)例變量的調(diào)用
- public class Fruits {
- public String fruitName;
- private int fruitNum;
- public static void main(String[] args) {
- Fruits fruits = new Fruits();
- fruits.fruitName = "strawberry";
- fruits.fruitNum = 100;
- }
- }
1. 如何識(shí)別實(shí)例變量
那么我如何知道一個(gè)變量它是實(shí)例變量呢?下面是一些關(guān)于實(shí)例變量的定義規(guī)則
- 實(shí)例變量可以使用四種訪問(wèn)修飾符進(jìn)行修飾:public、protected、default、private
- 實(shí)例變量可以使用 transient、final 關(guān)鍵字進(jìn)行修飾
- 實(shí)例變量不可以使用 abstract、synchronized、strictfp、native、static關(guān)鍵字進(jìn)行修飾
實(shí)例變量帶有默認(rèn)值,也就是說(shuō),實(shí)例變量不用初始化就能使用。下面是常用實(shí)例變量的初始值
2. 實(shí)例變量的特點(diǎn)
上面我們了解了實(shí)例變量的基本特征和如何區(qū)分實(shí)例變量,下面我們來(lái)講一下實(shí)例變量的特點(diǎn)。
- 實(shí)例變量的只能在類中聲明,但是在方法、構(gòu)造函數(shù)或任何塊之外。
- 當(dāng)在為堆中對(duì)象分配空間時(shí),將為每個(gè)實(shí)例變量分配一塊區(qū)域。
- 實(shí)例變量只能通過(guò)創(chuàng)建對(duì)象來(lái)使用,當(dāng)使用 new 關(guān)鍵字進(jìn)行創(chuàng)建對(duì)象時(shí),實(shí)例變量同時(shí)也被創(chuàng)建,當(dāng)垃圾回收器回收對(duì)象時(shí),實(shí)例變量也會(huì)被銷毀。
- 實(shí)例變量可以使用訪問(wèn)修飾符來(lái)修飾
- 實(shí)例變量不用強(qiáng)制初始化,它有自己的默認(rèn)值。
- 每個(gè)對(duì)象都有自己的一個(gè)實(shí)例變量的副本,因此在一個(gè)對(duì)象中修改變量不會(huì)對(duì)其他對(duì)象中的實(shí)例變量造成影響
- 實(shí)例變量只能通過(guò)創(chuàng)建對(duì)象引用來(lái)使用。
二、全局變量
全局變量又被稱為Global variables。如果你有其他語(yǔ)言的編程經(jīng)驗(yàn),比如 C、C++ 的話,你會(huì)接觸到全局變量這個(gè)概念,你可以使用下面代碼來(lái)創(chuàng)建全局變量
- #include<stdio.h>
- // 全局變量
- int A;
- int B;
- int Add()
- {
- return A + B;
- }
但是在 Java 中,是不存在全局變量的。因?yàn)?Java 是一門面向?qū)ο蟮木幊陶Z(yǔ)言,所有的內(nèi)容都是屬于類的一部分。Java 這么做的原因是為了防止數(shù)據(jù)和類成員被其他程序的其他部分有意或者無(wú)意的修改。所以在 Java 中,使用 靜態(tài)變量 來(lái)起到全局訪問(wèn)的目的。
三、靜態(tài)變量
靜態(tài)變量又被稱為Static variables。靜態(tài)變量的定義比較簡(jiǎn)單,靜態(tài)變量是屬于該類的變量,它是由 static 關(guān)鍵字來(lái)修飾的。static 修飾的變量屬于靜態(tài)變量,它只能定義在類的內(nèi)部、方法的外部。
靜態(tài)變量的特點(diǎn):
靜態(tài)變量只能使用 static 關(guān)鍵字進(jìn)行修飾,它不能在方法中進(jìn)行聲明,不論是靜態(tài)方法還是非靜態(tài)方法。
- 靜態(tài)變量會(huì)在程序運(yùn)行前進(jìn)行初始化,并且只初始化一次。靜態(tài)變量會(huì)有一個(gè)初始化順序,我們后面說(shuō)。
- 靜態(tài)變量的所有實(shí)例共享同一個(gè)副本。也就是說(shuō),靜態(tài)變量只有一個(gè),它不會(huì)隨著對(duì)象實(shí)例的創(chuàng)建而進(jìn)行副本拷貝
- 靜態(tài)變量可以通過(guò)類名.變量名 進(jìn)行訪問(wèn),并且不需要?jiǎng)?chuàng)建任何對(duì)象就能訪問(wèn)。
- public class Fruits {
- public String fruitName;
- private int fruitNum;
- static String fruitType;
- public static void main(String[] args) {
- Fruits.fruitType = "apple"; // 類名.變量名
- System.out.println(fruitType);
- }
- }
四、類變量
類變量又被稱為 Class variables在 Java 中,類變量就是靜態(tài)變量,它們都用 static 關(guān)鍵字進(jìn)行修飾,所以,如果你再聽到說(shuō)靜態(tài)變量的時(shí)候,它也就是類變量。
五、局部變量
還有一種說(shuō)法,說(shuō) Java 中只有類變量、實(shí)例變量和局部變量。這么分也沒(méi)有問(wèn)題,可能有人會(huì)問(wèn)到,你把成員變量和常量放在哪了?別著急我們后面會(huì)說(shuō)
先來(lái)說(shuō)一下什么是局部變量:
局部變量又稱為 Local variables。它指的是在方法中、構(gòu)造器中或者塊代碼中定義的變量。局部變量的生命周期隨方法、構(gòu)造器、代碼塊的執(zhí)行完畢而銷毀。
不管上面的一些變量概念如何變換、局部變量都站如松,坐如鐘,行如風(fēng),臥如弓,從容應(yīng)對(duì)各種不同文章的比較。真是一個(gè)省事的變量。
那么這么好的東西我們可要仔細(xì)研究一下其特點(diǎn)是啥:
- 根據(jù)定義可知,局部變量定義在方法、構(gòu)造器或者代碼塊中;
- 然后局部變量的生命周期隨方法、構(gòu)造器、代碼塊的執(zhí)行完畢而銷毀;
- 局部變量不能使用訪問(wèn)修飾符,例如如下代碼
- 局部變量?jī)H在方法的聲明、構(gòu)造函數(shù)或者塊內(nèi)可見,局部變量只能在調(diào)用這些方法、構(gòu)造函數(shù)或者塊的內(nèi)部使用
- 局部變量沒(méi)有默認(rèn)值,所以局部變量應(yīng)該在第一次使用或者聲明的時(shí)候就應(yīng)該初始化完成
六、成員變量
什么?成員變量在 Java 中就是實(shí)例變量?這個(gè)結(jié)論對(duì)嗎?
常量
驗(yàn)證過(guò)程為了驗(yàn)證這個(gè)結(jié)論,我們求助于 stackoverflow 網(wǎng)站
我們搜索 java member variable and instance variable 就幫我們定位到了這個(gè)標(biāo)題
大致意思是:什么是成員變量?成員變量和實(shí)例變量是否相同呢?我們下面有個(gè)回答
第一句就給出,實(shí)例變量和類變量都稱為成員變量,然后給出了 JDK 官網(wǎng)手冊(cè)對(duì)變量的定義。意思是在 Java 中,只有三種類型的變量
- 定義在類中的成員變量 --- 被稱為屬性
- 定義在方法(包含構(gòu)造方法)或者塊代碼中的變量 --- 被稱為局部變量
- 定義在方法定義中的變量 --- 被稱為參數(shù)
嗯。。?;蛟S還不是很好解決我們的問(wèn)題,我?guī)е鴨?wèn)題再次求助 JDK 官網(wǎng)手冊(cè),又看到了關(guān)于 Variables 的定義
意思是在 Java 中,只有下面幾種類型的變量(別扯別的了,莫非你比官網(wǎng)還靠譜?)
- 實(shí)例變量(非靜態(tài)屬性) :大致意思就是說(shuō)
- 非靜態(tài)屬性也就被稱為實(shí)例變量,因?yàn)樗鼈兊闹凳窍鄬?duì)于每個(gè)實(shí)例來(lái)說(shuō)的。換句話說(shuō),對(duì)于每個(gè)對(duì)象來(lái)講,實(shí)例變量的值都是唯一的;
- 類變量(靜態(tài)屬性):類變量就是使用 static 修飾符聲明的字段,這就會(huì)告訴編譯器:無(wú)論該類被實(shí)例化了多少次,該變量只存在一個(gè)副本。另外,可以添加關(guān)鍵字 final 來(lái)表示常量。
- 局部變量:沒(méi)有特殊的關(guān)鍵字將制定的變量聲明為局部變量、確定其聲明的完全取決于聲明變量的位置。
- 參數(shù):想一下我們平常用到最多的方法是什么方法?當(dāng)然是 main 方法啊,main 方法是怎么定義的?
- public static void main(String[] args) {}
其中的 args 是不是就是 String 的數(shù)組的變量,我們也稱其為參數(shù),所以參數(shù)也沒(méi)有關(guān)鍵字進(jìn)行聲明,標(biāo)識(shí)其為參數(shù)也只是取決于其聲明位置。
總結(jié)
所以我寫了一篇文章為了給你講清楚,現(xiàn)在你應(yīng)該知道 Java 中到底有哪些變量了吧。
如果你用 static 來(lái)定義變量,只能是類變量、或者說(shuō)靜態(tài)變量、而且其定義位置只能在類中,方法或代碼塊外,變量的副本只有一個(gè)。
如果你不用 static 來(lái)聲明變量,那么就會(huì)有三種變量的叫法
- 定義在構(gòu)造方法、代碼塊、方法外的變量被稱為實(shí)例變量,實(shí)例變量的副本數(shù)量和實(shí)例的數(shù)量一樣。
- 定義在方法、構(gòu)造方法、代碼塊內(nèi)的變量被稱為局部變量;
- 定義在方法參數(shù)中的變量被稱為參數(shù)。
也就是下面代碼所描述的這樣
- public class VariablesInJava {
- int instanceVariable; // 實(shí)例變量
- static String staticVariable; // 類變量
- public void method() {
- String localVariable = "localVariable"; // 局部變量
- System.out.println(localVariable);
- }
- public static void main(String args[]) {} //參數(shù)
- }