static關鍵字的作用
static意思是全局、靜態,用來修飾成員變量、成員方法、代碼塊。static所修飾的內容,可在整個程序內被所需要它的對象直接調用。靜態成員的數據保存在內存的數據共享區,並不單獨保存在每個對象的內存中,因此極大地節省了空間,優化了代碼結構,提高了運行效率。
1.static修飾成員變量
1.1靜態成員變量的訪問方式:
假設使用static修飾Demo2類內的某一個成員變量a,則a應該被通過靜態方式訪問,即通過其類名Demo2進行訪問。如果通過類對象demo2訪問,會提示警告!
class Demo2{
//創建並初始化一個靜態成員變量a
public static int a = 1;
}
public class Demo1 {
public static void main(String[] args) {
//創建一個Demo2的類對象
Demo2 demo2 = new Demo2();
//通過靜態成員變量所在的類的類對象調用該變量
System.out.println(demo2.a);
}
}
警告:The static field Demo2.a should be accessed in a static way
(使用static修飾的A類內的B成員變量,應該通過靜態方式訪問)
程序運行結果爲:1
雖然此時程序也可以運行,但是會出現警告,因此不建議使用類對象調用。
1.2靜態成員變量使用類名調用是沒有任何的問題。
與普通成員變量不同,普通成員變量需要通過類對象調用而不能直接通過類名調用,但是靜態成員變量直接通過類名調用沒有任何問題,或者說靜態成員變量就應該通過類名調用。
class Demo2{
//創建並初始化一個靜態成員變量b
public static int b = 1;
}
public class Demo1 {
public static void main(String[] args) {
//打印通過類名調用的靜態成員變量
System.out.println(Demo2.b);
}
}
運行結果:1
1.3靜態成員變量和當前類的類對象毫無關係。
- 在代碼中沒有創建對象時,可以通過類名直接使用靜態成員
- 代碼中對象已經被JVM的GC銷燬時,依然可以通過類名調用靜態成員變
1.4靜態成員變量的修改
不管通過哪一種方式調用靜態成員變量,修改對應的靜態成員變量數據,所有使用到當前靜態成員變量的位置,都會受到影響。
2.static修飾成員方法
2.1調用方式:
與靜態成員變量調用方式相同,靜態成員方法也推薦使用靜態方式調用,即通過類名調用
2.2使用其他成員
1.靜態成員方法中不能使用非靜態成員 ,包括非靜態成員方法和非靜態成員變量。【因爲沒有對象】
class Demo2{
//創建並初始化一個非靜態成員變量c
public int c = 1;
//創建靜態成員方法
public static void method() {
//使用非靜態非成員變量
System.out.println(c);
}
}
public class Demo1 {
public static void main(String[] args) {
}
}
程序報錯!
提示:Cannot make a static reference to the non-static field c
(不能對非靜態字段c進行靜態引用)
- 靜態成員方法中不能使用this關鍵字。【因爲沒有對象】
- 靜態成員方法中可以使用類內的其他靜態成員。【因爲大家都是靜態的,是同類】
- 靜態成員方法中可以通過new 構造方法創建對象
3.static修飾代碼塊
代碼塊:
構造代碼塊:初始化當前類的所有類對象,只要調用構造方法,一定會執行對應的構造代碼塊。
靜態代碼塊:初始化程序,只要類文件加載,靜態代碼塊中所有內容全部執行。
局部代碼塊:提高效率,解決內存,讓JVM回收內存的效率提升。
4.使用及執行規則
4.1修飾內容
static只能修飾以上三個,一般不能修飾類,只有一種特殊用法可以用static修飾內部類,但普通類不能用static修飾。
4.2執行順序
所有的static修飾的內容在整個程序中執行優先級最高(不論在代碼裏的順序如何),其次是main()方法,然後是構造代碼塊,最後普通代碼。
一個順序題:
public class Demo1 {
{
System.out.println("構造代碼塊");
}
static {
System.out.println("靜態代碼塊");
}
public Demo1() {
System.out.println("構造方法");
}
public static void main(String[] args) {
System.out.println("main方法");
Demo1 demo1 = new Demo1();
}
}
執行結果:
靜態代碼塊
main方法
構造代碼塊
構造方法