(注:靜態變量修改為靜態成員變量,靜態方法改為靜態成員方法)
靜態成員變量又稱類變量,靜態成員方法又稱類方法,它們統稱為靜態成員或類成員。靜態成員由static修飾,是屬於整個類的,所有的對象共享這些靜態成員。不需要創建任何對象,靜態成員在類裝載時就已初始化了,整個運行期間其內存位置不變,直到類卸載。鑒於靜態成員的這些特性,訪問靜態成員變量以及定義或調用靜態成員方法時與非靜態成員也有不同之處。下面分別做出說明。
1.靜態成員變量
- 類的非靜態成員方法、靜態成員方法都可以直接訪問靜態成員變量
- 其他類要訪問某個類的靜態成員變量,既可以通過實例名訪問,也可以直接用類名來訪問,推薦用類名訪問的方式,這樣能更直觀的說明訪問的變量是靜態成員變量
2.靜態方法
- 不能直接訪問非靜態成員變量,也不能直接調用非靜態成員方法,需要實例化一個對象,再通過該對象來訪問要訪問的非靜態成員變量或要調用的非靜態成員方法。也就是說,靜態成員方法不能直接使用非靜態成員。個人理解是,非靜態成員變量是依托對象而存在的,當沒有實例一個對象時,非靜態成員變量是沒有分配內存空間的,靜態方法要使用非靜態成員變量不知道要到哪里去找,當然就不能直接使用非靜態成員變量了。而非靜態成員方法有有可能訪問非靜態成員變量,所以也不能直接調用非靜態成員方法了。
- 其他類要調用某個類的靜態成員方法,既可以通過實例名調用,也可以直接用類名來調用,推薦用類名調用的方式,這樣能更直觀的說明調用的方法是靜態成員方法
3.下面以簡單的代碼驗證上面的結論
定義了一個Person類,類的代碼見最后面。
(1).類的靜態成員方法和非靜態成員方法都可以直接訪問靜態成員變量
- 靜態成員方法staticMethod訪問了靜態成員變量citizenship
- 定義並使用了局部變量testY
- 非靜態成員方法informationPrint訪問了靜態成員變量citizenship
staticMethod()方法如下:
public static void staticMethod() { int testY = 20; System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access
}
informationPrint()方法如下:
public void informationPrint() { System.out.println("My name is " + getName()); System.out.println("I am " + getAge() + " years old"); if(getGender() == "female") System.out.println("I am a girl"); else if(getGender() == "male") System.out.println("I am a boy"); else System.out.println("Something is wrong!"); System.out.println("My hobby is " + hobby); if(citizenship == "Chinese") System.out.println("I am a chinese"); else if(citizenship == "US") System.out.println("I am an American"); else System.out.println("Oh,something is wrong"); }
main()方法如下:
public static void main(String[] args) { Person xiaoxi = new Person("xiaoxi",29,"female","piano"); xiaoxi.informationPrint(); staticMethod(); }
輸出結果如下:
My name is xiaoxi I am 29 years old I am a girl My hobby is piano I am a chinese She has applied for Chinese citizenship She's now 20 years old
結果分析:
- 靜態成員方法可以直接訪問靜態成員變量
- 靜態成員方法可以自定義局部變量
- 非靜態成員方法可以直接訪問靜態成員變量
(2),靜態成員方法不可以直接訪問非靜態成員變量
[1].staticMethod直接訪問靜態成員變量citizenship,出現錯誤
- 靜態成員方法staticMethod訪問了靜態成員變量citizenship
- 定義並使用了局部變量testY
- 訪問了非靜態成員變量hobby
staticMethod()方法如下:
public static void staticMethod() { int testY = 20; System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access System.out.println("She doesn't like " + hobby); //nonstatic variable access }
main方法同上。
輸出結果如下:
My name is xiaoxi I am 29 years old I am a girl My hobby is piano I am a chinese Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot make a static reference to the non-static field hobby at human.Person.staticMethod(Person.java:99) at human.Person.main(Person.java:107)
結果分析:
- 靜態成員方法不能直接訪問非靜態成員變量,否則會出現“Cannot make a static reference to the non-static field hobby” 的錯誤。
[2].staticMethod()創建一個對象testP,由testP訪問非靜態成員變量hobby,成功執行
- 靜態成員方法staticMethod使用了靜態成員變量citizenship
- 定義並使用了局部變量testY
- 創建一個Person實例testP,並使用了testP的變量hobby
staticMethod()方法如下:
public static void staticMethod() { int testY = 20; Person testP = new Person(); System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access System.out.println("She doesn't like " + testP.hobby); // nonstatic variable access via object instance testP }
main方法同上。
輸出結果如下:
My name is xiaoxi I am 29 years old I am a girl My hobby is piano I am a chinese She has applied for Chinese citizenship She's now 20 years old She doesn't like null
結果分析:
- 靜態成員方法要訪問非靜態成員變量,可以先實例化一個對象,再通過對象訪問。
(3),靜態成員方法不可以直接調用非靜態成員方法
[1].staticMethod()直接訪問非靜態成員方法informationPrint(),出現錯誤
- 靜態成員方法staticMethod使用了靜態成員變量citizenship
- 定義並使用了局部變量testY
- 創建一個Person實例testP,並使用了testP的hoppy變量
- 直接調用非靜態成員方法informationPrint()
staticMethod()方法如下:
public static void staticMethod() { int testY = 20; Person testP = new Person(); System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access //System.out.println("She doesn't like " + testP.hobby); //nonstatic variable access System.out.println("She doesn't like " + testP.hobby); // nonstatic variable access via object instance testP System.out.println("Her personal information is as follows:"); informationPrint(); }
main()方法同上。
輸出結果如下:
My name is xiaoxi I am 29 years old I am a girl My hobby is piano I am a chinese Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot make a static reference to the non-static method informationPrint() from the type Person at human.Person.staticMethod(Person.java:103) at human.Person.main(Person.java:111)
結果分析:
- 靜態成員方法不能直接調用非靜態成員方法,否則會出現與直接訪問非靜態成員變量類似的錯誤,Cannot make a static reference to the non-static method informationPrint() from the type Person。
[2].通過已有對象testP來調用informationPrint()方法,成功執行
- 靜態成員方法staticMethod使用了靜態成員變量citizenship
- 定義並使用了局部變量testY
- 創建一個Person實例testP,並使用了testP的hoppy變量
- 通過testP調用非靜態成員方法informationPrint()
staticMethod()方法如下:
public static void staticMethod() { int testY = 20; Person testP = new Person(); System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access System.out.println("She doesn't like " + testP.hobby); // nonstatic variable access via object instance testP System.out.println("Her personal information is as follows:"); //informationPrint(); testP.informationPrint(); }
main()方法同上。
輸出結果如下:
My name is xiaoxi I am 29 years old I am a girl My hobby is piano I am a chinese She has applied for Chinese citizenship She's now 20 years old She doesn't like null Her personal information is as follows: My name is null I am 0 years old Something is wrong! My hobby is null I am a chinese
結果分析:
- 靜態成員方法要調用非靜態成員方法,可以先實例化一個對象,再通過該對象來調用。
(4).其他類通過類名直接調用類的靜態成員變量和靜態成員方法
- 類TestMain通過類名Person直接調用了靜態成員方法staticMethod()和靜態成員變量citizenship
TestMain如下:
package human; public class TestMain { public static void main(String[] args) { Person.staticMethod(); System.out.println("static variable \"citizenship\":" + Person.citizenship); } }
輸出結果如下:
She has applied for Chinese citizenship She's now 20 years old She doesn't like null Her personal information is as follows: My name is null I am 0 years old Something is wrong! My hobby is null I am a chinese static variable "citizenship":Chinese
附Person類:
package human; public class Person { String name; int age; String gender; private String hobby; protected String residence; static String citizenship = "Chinese"; public Person() { } public Person(String n, String g) { this.name = n; this.gender = g; } public Person(String n, int a, String g, String h) { this.name = n; this.age = a; this.gender = g; this.hobby = h; //test:靜態變量初始化的時機是否在構造方法之前 // System.out.println("constructor:"); // System.out.println("change value of the static variable citizenship " + "\"" + citizenship + "\""); // citizenship = "US"; // System.out.println(" to " + "\"" + citizenship + "\""); } public Person(String n, int a, String g, String h, String r) { this.name = n; this.age = a; this.gender = g; this.hobby = h; this.residence = r; } public void setName(String n) { this.name = n; } public void setAge(int a) { this.age = a; } public void setGender(String g) { this.gender = g; } public void setHobby(String h) { this.hobby = h; } public void setResidence(String r) { this.residence = r; } public String getName() { return this.name; } public int getAge() { return this.age; } public String getGender() { return this.gender; } public String getHobby() { return this.hobby; } public String getResidence() { return this.residence; } public void informationPrint() { System.out.println("My name is " + getName()); System.out.println("I am " + getAge() + " years old"); if(getGender() == "female") System.out.println("I am a girl"); else if(getGender() == "male") System.out.println("I am a boy"); else System.out.println("Something is wrong!"); System.out.println("My hobby is " + hobby); if(citizenship == "Chinese") System.out.println("I am a chinese"); else if(citizenship == "US") System.out.println("I am an American"); else System.out.println("Oh,something is wrong"); } public static void staticMethod() { int testY = 20; Person testP = new Person(); System.out.println("She has applied for " + citizenship + " citizenship"); //static variable access System.out.println("She's now " + testY + " years old"); //local variable access System.out.println("She doesn't like " + testP.hobby); // nonstatic variable access via object instance testP System.out.println("Her personal information is as follows:"); //informationPrint(); testP.informationPrint(); } public static void main(String[] args) { Person xiaoxi = new Person("xiaoxi",29,"female","piano"); xiaoxi.informationPrint(); staticMethod(); } }