一、為什麼需要靜態變量?
因為成員變量會隨著對象的創建而在堆一直存在,每個對象在內存中都有一份成員變量
這樣子會造成每創建一個對象,就會創建對應的成員變量,浪費空間
* 對於共用的,多個對象共享的成員變量,使用static修飾稱為靜態變量,在內存中產生一份數據,不會浪費
* 靜態變量:被所有對象共用,在內存中只會產生一份數據
二、static關鍵字
1.靜態變量的定義格式
格式: 權限修飾符 static 數據類型 變量名;
範例: public static String country;
2.靜態變量的調用格式
格式1:使用類名訪問(推薦)
範例:Student.school="清華";
格式: 使用對象名訪問(不推薦)
範例: Student stu1=new Student();
stu1.school="北大";
3.靜態變量和普通變量(非靜態變量)的區別
區別:
1.定義不同
類變量(靜態變量)定義時候前面要加上static
實例變量(非靜態變量)不需要加
2.初始化不同
類變量(靜態變量)隨著類的加載而初始化
實例變量(非靜態變量) 是new對象後才進行初始化
3.內存位置不同
類變量(靜態變量)隨著類的加載而存在於「方法區」中
實例變量(非靜態變量)存儲在「堆內存區」
4.調用方式不同
類變量(靜態變量)通過類名調用
實例變量(非靜態變量)通過對象調用
5.生命周期不同
類變量(靜態變量)隨著類的加載而加載,虛擬機停止運行類時,靜態變量周期結束(類變量生命周期最長,隨著類的消失而消失)
實例變量(非靜態變量)隨著對象的產生而產生,隨著對象的消失而失去引用,等待垃圾回收(隨著對象的消失而消失)
tips
可以將static理解為同步修改,你變我也變,改變的都是同一份數據
4.靜態變量小結
三、靜態方法
1.什麼是靜態方法?
使用static修飾的方法,叫做靜態方法
2.靜態方法的格式
格式:權限修飾符 static 返回值類型 方法名(參數){
方法體;
return 數據;
}
範例: public static int add(int a,int b){
int c=a+b;
return c;
}
3.靜態方法的調用格式
格式1:類名.靜態方法名(); (推薦) //在本類中調用靜態方法,可以省略類名
範例:Student.method();
格式2:對象名.靜態方法名(); (不推薦)
範例:Student stu=new Student();
stu.method();
4.靜態方法和普通成員方法的區別
區別:
"格式區別:"
1.靜態方法需要static關鍵字修飾,必須有返回類型,可以沒有返回值 (只能訪問靜態變量,靜態方法) //靜態訪問靜態
2.成員方法可以任意起名,必須有返回類型,可以沒有返回值 (可以訪問任意變量,任意方法)
"調用區別:"
1.靜態方法在本類中可以直接方法名調用,其他類中用類名.方法名調用 //show(); Student.show();
2.成員方法需要通過 對象名.方法名()才可以調用,可以調用多次 // stu.show();
5.案例
public class Student {
public static void method(){
System.out.println("學習");
}
public void eat(){
System.out.println("吃飯");
}
int age;
static String name;
public static void method2(){
System.out.println(name);
//靜態方法只能訪問靜態變量,從內存圖來理解,靜態變量是隨著類的加載而加載,先存在,而成員變量是new對象後才產生的,所以訪問不到
System.out.println(age); //報錯
System.out.println(this);
//報錯,因為this代表的是當前調用類的對象,而靜態方法屬於類範圍的東西,靜態優於對象存在,不能調用
System.out.println(super);
//super代表對父類對象的引用,指向父類對象;而靜態方法比對象先出現
}
//成員方法訪問任意變量,任意方法
public void method3(){
eat();
method();
System.out.println(age);
System.out.println(name);
System.out.println(this);
}
}
執行效果
tips
this和super是屬於對象範疇的東西,而靜態和靜態方法是屬於類範疇的東西,比對象先出現,因為是隨著類的加載而初始化
靜態只能訪問靜態的東西