1.static靜態關鍵字概述
關於 static 關鍵字的使用,它可以用來修飾的成員變量和成員方法,被修飾的成員是屬於類的,而不是單單是屬 於某個對象的。也就是說,既然屬於類,就可以不靠創建對象來調用了。
在一個類中,有變量和方法,而變量有成員變量,靜態變量;而方法有成員方法和靜態方法之分(只要帶static關鍵字就代表靜態變量或方法)
如何區分我們什麼時候使用static關鍵字呢?
從上述圖中我們可以看出在學生類中,我們new三個學生對象,每一個對象除了姓名,年齡,學號不同之外,每一個學生對象的所在教室完全一樣。
對於姓名,年齡,學號來說,每一個對象都有自己獨立的數據。但對於所在的教室來說,這應該是多個對象共享同一份數據纔對。
一旦使用了static關鍵字,那麼這樣的內容不在屬於對象自己,而是屬於類的,所以凡是本類的對象,都共享同一份。
我們來實現這個圖片展示的功能(以標準的類的創建方式):
package com.bytedance;
public class staticDemo {
public static void main(String[] args) {
// 靜態static常量賦初值(類名稱.變量名)
Student1.room = "101教室";
Student1 one = new Student1("郭靖", 20);
System.out.println("one的姓名:" + one.getName());
System.out.println("one的年齡:" + one.getAge());
System.out.println("one的教室:" + Student1.room);
System.out.println("============");
Student1 two = new Student1("黃蓉", 18);
System.out.println("two的姓名:" + two.getName());
System.out.println("two的年齡:" + two.getAge());
System.out.println("two的教室:" + Student1.room);
myMethod() // 本類中的靜態方法直接調用
}
// 本類中的靜態方法,調用時可以省略類名稱,直接調用
public static void myMethod() {
System.out.println("自己的方法!");
}
}
class Student1 {
private int id; // 學號
private String name; // 姓名
private int age; // 年齡
static String room; // 所在教室
private static int idCounter = 0; // 學號計數器,每當new了一個新對象的時候,計數器++
public Student1() {
this.id = ++idCounter;
}
public Student1(String name, int age) {
this.name = name;
this.age = age;
this.id = ++idCounter;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.靜態變量
靜態變量 : static 數據類型 變量名 (static int numberID)
比如說,基礎班新班開班,學員報到。現在想爲每一位新來報到的同學編學號(sid),從第一名同學開始,sid爲 1,以此類推。學號必須是唯一的,連續的,並且與班級的人數相符,這樣以便知道,要分配給下一名新同學的學 號是多少。這樣我們就需要一個變量,與單獨的每一個學生對象無關,而是與整個班級同學數量有關
package com.bytedance;
public class staticDemo {
public static void main(String[] args) {
Student1 s1 = new Student1("迪麗熱巴",18);
Student1 s2 = new Student1("古力娜扎",20);
Student1 s3 = new Student1("馬爾扎哈",33);
s1.show(); // Student : name=迪麗熱巴, age=18, 學生編號=1
s2.show(); // Student : name=古力娜扎, age=20, 學生編號=2
s3.show(); // Student : name=馬爾扎哈, age=33, 學生編號=3
}
}
class Student1{
// 成員變量
private String name;
private int age;
// 學生的id
private int id;
// 靜態變量,記錄學生數量,分配學號
public static int numberNo = 0;
public Student1(String name,int age){
this.name = name;
this.age = age;
// 表示每創建一個Student1對象,id就會自動加一
this.id = ++ numberNo;
}
// 打印屬性值
public void show() {
System.out.println("Student : name="+this.name+", age="+this.age+", 學生編號="+this.id);
}
}
3.靜態方法
使用格式: 修飾符 static 返回值類型 方法名 (參數列表){ // 執行語句代碼塊 }
被static修飾的成員可以並且建議通過類名直接訪問。雖然也可以通過對象名訪問靜態成員,原因即多個對象均屬 於一個類,共享使用同一個靜態成員,但是不建議,會出現警告信息。
package com.bytedance;
public class staticDemo {
public static void main(String[] args) {
MyClass obj = new MyClass(); // 首先創建對象
obj.num = 18;
MyClass.numStatic = 20;
// 創建對象之後,然後才能使用沒有static關鍵字的內容
obj.method();
// 對於靜態方法來說,可以通過對象名進行調用,也可以直接通過類名稱來調用。
obj.methodStatic(); // 正確,不推薦,這種寫法在編譯之後也會被javac翻譯成爲“類名稱.靜態方法名”
MyClass.methodStatic(); // 正確,推薦
// 對於本類當中的靜態方法,可以省略類名稱
myMethod();
staticDemo.myMethod(); // 對於本類中的靜態方法,myMethod()與staticDemo.myMethod()完全等效,可以省略類名稱
}
public static void myMethod() {
System.out.println("自己的方法!");
}
}
class MyClass {
int num; // 成員變量
static int numStatic; // 靜態變量
// 成員方法
public void method() {
System.out.println("這是一個成員方法。");
// 成員方法可以訪問成員變量
System.out.println(num);
// 成員方法可以訪問靜態變量
System.out.println(numStatic);
}
// 靜態方法
public static void methodStatic() {
System.out.println("這是一個靜態方法。");
// 靜態方法可以訪問靜態變量
System.out.println(numStatic);
// 靜態不能直接訪問非靜態【重點】
// System.out.println(num); // 錯誤寫法!
// 靜態方法中不能使用this關鍵字。
// System.out.println(this); // 錯誤寫法!
}}
4. 總結
一旦使用static修飾成員方法,那麼這就成爲了靜態方法。靜態方法不屬於對象,而是屬於類的。
如果沒有static關鍵字,那麼必須首先創建對象,然後通過對象才能使用它。
如果有了static關鍵字,那麼不需要創建對象,直接就能通過類名稱來使用它。
無論是成員變量,還是成員方法。如果有了static,都推薦使用類名稱進行調用。
靜態變量\:類名稱.靜態變量
靜態方法\:類名稱.靜態方法()
靜態常量賦初始值的方法:類名稱.靜態變量名 = 初始值
注意事項:
-
靜態方法只能訪問靜態成員,實例方法可以訪問靜態和實例成員。反之,成員方法可以直接訪問類變量或靜態方法
原因:因爲在內存當中是【先】有的靜態內容,【後】有的非靜態內容。
“先人不知道後人,但是後人知道先人。” -
靜態方法當中不能用this。
原因:this代表當前對象,通過誰調用的方法,誰就是當前對象。 -
對於本類當中的靜態方法,調用時可以省略類名稱