Java數組是靜態的—由於java語言是靜態的java
靜態是指,當一個數組被初始化了以後,其長度是不可變的,而且數組必須通過初始化才能使用。(見下面特例)數組
int[] int_arr_3 = null; //int_arr_3指向null,可是因爲未訪問其引用的數組對象,因此這句不會報NullPointer System.out.println(int_arr_3); //使用int_arr_3.length,訪問了該數組所引用的對象,因此會報空指針 //System.out.println(int_arr_3.length);
靜態初始化:初始化的時候指定初始值,由系統決定長度spa
int[] int_arr_1 = new int[]{43,56,74,23,25};指針
動態初始化:初始化時只指定長度,由系統分配初始值code
int[] int_arr_2 = new int[5];對象
指定的初始值規則以下:內存
不要同時使用靜態初始化和動態初始化~!it
數組中的元素類型一致內存管理
數組變量是引用類型的變量,如圖:class
a1,a2,a3是三個數組,位於棧內存,他們都是引用類型變量,指向的是對內存的數組對象,因此當數組被初始化之後,堆內存裏面的數組對象長度就不可變了,可是能夠將數組指向(引用)其它的數組對象,形成數組可變的假象
那麼在這裏能夠想象,數組不必定要初始化,由於他是引用變量,那麼當他被聲明以後(只是被分配了棧內存),只要讓數組元素指向有效的數組對象(至關於初始化),那麼該數組就能夠被使用。
int arr = new int[]{1,2};
arr指的是數組,而若是arr經過引用訪問屬性或者調用方法,那麼此時的數組就是數組對象自己。
int a = 10;
int b = 20;
arr[0] = a;
b = arr[1];
都是能夠的
在已有的數組類型後面加上[],即產生了一個新數組
同理,將數組最後面的[]去掉,即獲得了該數組存儲的類型
因此,數組元素就是變量
多維數組
int a[][]
考慮到數組是引用類型,因此多維數組便是一維數組的每一個元素引用的是另一個(一維)數組,看起來就成了多維數組
內存管理分爲兩個方面:
內存分配和內存回收
內存分配:建立java對象時,JVM爲該對象在堆內存裏分配內存空間
內存回收:當java對象失去引用以後,變成「垃圾」,將會被JVM清理
實例變量和類(靜態)變量
實例變量分爲局部變量和成員變量
局部變量:
類體內定義的變量稱爲成員變量(Field),其又分爲非靜態變量和靜態變量
//下面的代碼將提示:非法向前引用
int num1 = num2 + 2;
int num2 = 20;
//下面正常
int num1 = num2 +2;
static num2 = 20;
在同一個JVM內,每個類只對應一個Class對象,故只須要一塊內存空間,可是卻能夠建立多個類對象,每建立一個對象,就要爲該對象分配內存空間。
因此,類(靜態)變量會在類初始化的時候初始化,分配內存,而建立對象的時候則不會再爲靜態變量分配內存了,只會爲非靜態類變量分配內存。
靜態變量不能夠訪問非靜態變量,可是非靜態變量卻能夠訪問靜態變量,而且,也能夠經過對象實例來訪問靜態變量,和經過類來訪問效果同樣
執行順序
JVM對每個類只執行一次初始化操做,只爲類變量分配一次內存空間,執行一次初始化
有兩個地方對類變量執行初始化:
1:定義類變量是執行初始值
2:在靜態初始化塊中對類變量執行初始化
執行順序與他們在代碼中的順序一致
代碼分析:
程序輸出值不是兩個17.2,而是-2.8和17.2
分析:
首先將初始化分爲兩個步驟:
1:系統爲price的兩個類變量分配內存空間
2:按初始化代碼的排列順序對類變量初始化
第一階段:系統先爲INSTANCE,price分配內存空間,此時他們的默認值都是0.0
第二階段:程序按順序分別爲他們賦值,首先是INSTANCE,他的值是new Price(2.8),即建立Price實例,調用構造方法:0.0 – 2.8 = -2.8,注意此時的initPrice是0.0~!!!,那麼獲得的currentPrice是-2.8,而後程序再對initPrice賦值:20,可是此時initPrice對INSTANCE已經沒有影響了~!
當Price類初始化完成以後,INSTANCE引用到的currentPrice爲-2.8,即輸出-2.8,當再次構造Price對象,此時InitPrice爲20.0,因此獲得currentPrice爲17.2