1、成員變量和局部變量簡述
在JAVA語言里,根據(jù)定義變量位置的不同,可以將變量分成兩大類:成員變量和局部變量。二者的運行機制存在較大差異。
1.1 成員變量
類變量從該類的準備階段起開始存在,直到系統(tǒng)完全銷毀這個類,類變量的作用域與這個類的生存范圍相同;
而實例變量則從該類的實例被創(chuàng)建起開始存在,直到系統(tǒng)完全銷毀這個實例,實例變量的作用域與對應(yīng)實例的生存范圍相同。
正是基于這個原因,可以把類變量和實例變量統(tǒng)稱為成員變量。
其中類變量可以理解為類成員變量,它作為類本身的一個成員,與類本身共存亡;實例變量則可以理解為實例成員變量,它作為實例的一個成員與實例共存亡。
只要類存在,類就可以訪問類變量 -- 類.類變量
只要實例存在,實例就可以訪問實例變量 -- 實例.實例變量
當然實例也可以訪問類變量。但是需要注意的是因為實例不擁有類變量,所以通過實例來訪問類變量進行操作,實際上是對類變量進行操作,當有其他實例來訪問類變量時,訪問的類變量是被對象訪問操作過的類變量。
成員變量無需顯示初始化,只要為一個類定義了類變量或?qū)嵗兞浚到y(tǒng)就會在這個類的準備階段或創(chuàng)建該類的實例時進行默認初始化。
1.2 局部變量
局部變量根據(jù)定義形式的不同,又可以分為如下三種:
- 形參:在定義方法簽名時定義的變量,形參的作用域在整個方法中都有效
- 方法局部變量:在方法體內(nèi)定義的局部變量,它的作用域是從定義該變量的地方生效,到該方法結(jié)束時失效
- 代碼塊局部變量:這個局部變量的作用域從定義該變量的地方生效,到該代碼結(jié)束時失效。
一個變量只在一對{ }中起作用。
Java允許局部變量和成員變量同名,如果方法中局部變量和成員變量同名,局部變量就會覆蓋成員變量,如果需要在這個方法中引用被覆蓋成員變量,則可使用this(對于實例變量)或類名(對于類變量)作為調(diào)用者來限定訪問成員變量。
2、成員變量的初始化和內(nèi)存中的運行機制
接下來以下面代碼來舉例說明成員變量的初始化和內(nèi)存中的運行機制
public class Person {
public static int num;
public String name;
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
p1.num = 2;
p2.num = 3;
p1.name = "張三";
p2.name = "李四";
}
}
當程序執(zhí)行Person p1 = new Person();時,如果這行代碼是第一次使用Person類,則系統(tǒng)通常會在第一次使用Person類時加載這個類,并初始化這個類,在類的準備階段,系統(tǒng)將會為該類的類變量分配內(nèi)存空間,并指定默認初始值。當Person類初始化完成后,系統(tǒng)內(nèi)存中的存儲示意圖如下圖所示。
可以看出,當Person類初始化完成后,系統(tǒng)將在堆內(nèi)存中為Person分配一塊內(nèi)存空間,實際上是創(chuàng)建了一個類對象,在這塊內(nèi)存區(qū)里包含了保存num類變量的內(nèi)存,并設(shè)置num的默認初始值為0。
系統(tǒng)接著創(chuàng)建了一個Person對象,并把這個Person對象賦給p1變量,Person對象包含了名為name的實例變量,實例變量是在創(chuàng)建實例時分配內(nèi)存空間并指定初始值的。當創(chuàng)建了第一個person對象后,系統(tǒng)內(nèi)存中的存儲示意圖如下圖所示。
從上圖可以看出num不屬于對象,它屬于類,所以創(chuàng)建第一個對象時并不需要為num分配內(nèi)存空間,系統(tǒng)只是為name分配了內(nèi)存空間,并指定初始值為null。
創(chuàng)建第二個對象p2時,由于在創(chuàng)建第一個對象時已經(jīng)對類進行了初始化,所以在創(chuàng)建p2時對類進行初始化,對象的創(chuàng)建過程與第一個對象的創(chuàng)建過程沒有什么區(qū)別。
第二個對象創(chuàng)建完成后,成員變量如上圖所示在內(nèi)存中存儲。
當程序需要訪問類變量時,盡量使用類來作為主調(diào),不要使用對象作為主調(diào),這個可以避免產(chǎn)生歧義。
3、局部變量的初始化和內(nèi)存中的運行機制
- 局部變量必須經(jīng)過顯示初始化之后才能使用,系統(tǒng)不會為局部變量執(zhí)行初始化。定義了局部變量以后,系統(tǒng)并沒有給局部變量進行初始化,直到程序給這個局部變量賦給初值時,系統(tǒng)才會為這個局部變量分配內(nèi)存空間,并將初始值保存到這塊內(nèi)存中。
- 局部變量不屬于任何類或者實例,因此它總是保存在方法的棧內(nèi)存中。如果局部變量是基本數(shù)據(jù)類型,則該變量直接存儲在方法的棧內(nèi)存中,如果是引用變量則將引用的地址存儲在方法的棧內(nèi)存中。
- 棧內(nèi)存中的變量無需系統(tǒng)垃圾回收,隨著方法或者代碼塊的運行結(jié)束而結(jié)束。局部變量通常只保存了具體的值或者引用地址,所以所占的內(nèi)存比較小。
4、變量的使用規(guī)則
- 能不使用成員變量就別使用成員變量;
- 能不使用方法局部變量就別使用方法局部變量;
- 使用代碼塊局部變量性能最好;
原文鏈接:
Java面向?qū)ο?mdash;—成員變量和局部變量(成員變量和局部變量的初始化和內(nèi)存運行機制&變量的使用規(guī)則)
https://www.cnblogs.com/newveg/p/6591435.html