局部變量:方法中定義的變量。
成員變量(類似C中的全局變量):成員變量定義在方法體和語句塊之外。成員變量就概括描述了類中的變量,不區分static。是以下變量的統稱。
類變量(靜態變量):獨立於方法之外的變量,屬於類本身。需要static修飾,事實上,類變量就是以static修飾的獨立於方法之外的成員變量。
- 類變量必須在方法、構造方法和語句塊之外。
- 無論一個類創建了多少個對象,類只擁有類變量的一份拷貝。
實例變量(非靜態變量):獨立於方法之外的變量,依賴實例存在。不需要static修飾,事實上,實例變量就是沒有static修飾的獨立於方法之外的成員變量。
- 實例變量聲明在一個類中,但在方法、構造方法和語句塊之外。
- 當一個對象被實例化之后,每個實例變量的值就跟着確定。
- 實例變量在對象創建的時候創建,在對象被銷毀的時候銷毀。
- 實例變量的值應該至少被一個方法、構造方法或者語句塊引用,使得外部能夠通過這些方式獲取實例變量信息。
- 實例變量可以聲明在使用前或者使用后。
- 實例變量對於類中的方法、構造方法或者語句塊是可見的。一般情況下應該把實例變量設為私有。通過使用訪問修飾符可以使實例變量對子類可見。
- 實例變量具有默認值。數值型變量的默認值是0,布爾型變量的默認值是false,引用類型變量的默認值是null。變量的值可以在聲明時指定,也可以在構造方法中指定。
Example(from CoreJava):
假定公司需要給每一個雇員賦予唯一的標識碼。
分析:每一個雇員對象都有一個自己的id域,但這個類的所有實例將共享一個nextld 域。換句話說,如果有 1000 個Employee類的對象,則有 1000 個實例域 id。但是,只有一個靜態域 nextld。即使沒有一個雇員對象,靜態域 nextld 也存在。它屬於類,而不屬於任何獨立的對象。
代碼如下(以員工jack作為第一名員工簡單示例):
1 public class Employee { 2
3 public static int nextId=1; 4 public int id; 5 public void setId(){ //該方法意味着下面new的對象jack的id域(實例域)被設置為靜態域nextld當前的值(1),並且靜態域nextld的值加1
6 id=nextId; 7 nextId++; 8 } 9
10 public void method(){ //定義一個用於輸出標識碼的非靜態方法
11 System.out.println(id); 12 } 13
14 public static void main(String[] args){ 15 Employee jack=new Employee(); //new一個叫jack的員工
16 jack.setId(); //調用setId方法為jack分配一個標識碼
17 jack.method(); //調用method方法輸出jack的標識碼
18 } 19
20 }
注:無法在靜態變量中引用非靜態成員(非靜態變量,非靜態方法),因為非靜態的變量是依賴於對象存在的,對象必須實例化之后,它的變量才會在內存中存在。
解決方案:一、將變量變為靜態變量,在變量類型前增加static。
二、先實例化一個對象,然后使用 對象名.變量名 來引用即可。
代碼如下:
1 //以下為第二種方法,第一種方法只需在第四行public和String之間增加static即可(name即變為靜態變量)
2 public class Test { 3
4 public String name; //name為非靜態變量
5
6 public static void main(String[] args){ 7 Test learner=new Test(); //在主方法(為靜態方法)中要調用非靜態變量name,需要先實例化一個對象learner
8 learner.name="西柚冬瓜"; //然后采用 對象名.變量名 方式來在主方法中引用非靜態變量name
9 System.out.println(learner.name); 10 } 11
12 }