- 1. static關鍵字
- 1.1概述
- 1.2修飾一個成員變量
- 例:
- 1.2.1靜態屬性與非靜態屬性示例及內存圖對比
- 1.3修飾一個方法(靜態方法)
- 1.4.static修飾成員的訪問特點總結
- 1.5動態代碼塊和靜態代碼塊
- 1.5.1動態代碼塊
- 1.5.2 靜態代碼塊
- 1.6帶有繼承的對象創建過程
1. static關鍵字
1.1概述
1.概述:static是一個靜態關鍵字
2.使用:a.修飾一個成員變量:static 數據類型 變量名b.修飾一個方法:修飾符 static 返回值類型 方法名(形參){方法體return 結果}3.調用靜態成員:類名直接調用(不用new對象)4.靜態成員特點:a.靜態成員屬于類成員,不屬于對象成員(非靜態的成員屬于對象成員)b.靜態成員會隨著類的加載而加載c.靜態成員優先于非靜態成員存在在內存中d.凡是根據靜態成員所在的類創建出來的對象,都可以共享這個靜態成員
1.2修飾一個成員變量
例:
public class Student {String name;int age;static String classRoom;
}
public class Test01 {public static void main(String[] args) {//先給靜態成員賦個值 類名直接調用(不用new對象) Student.classRoom = "222";Student s1 = new Student();s1.name = "郭靖";s1.age = 28;//s1.classRoom = "111";System.out.println(s1.name+","+s1.age+","+Student.classRoom);System.out.println("==============");Student s2 = new Student();s2.name = "黃蓉";s2.age = 26;//s2.classRoom = "111";System.out.println(s2.name+","+s2.age+","+Student.classRoom);}
}
1.2.1靜態屬性與非靜態屬性示例及內存圖對比
public class MyClass {public int a; //實例屬性
}public class MyTest1 {public static void main(String[] args) {MyClass c1 = new MyClass();c1.a = 20;MyClass c2 = new MyClass();c2.a = 30;System.out.println("c1.a = " + c1.a);System.out.println("c2.a = " + c2.a);}
}
實例屬性是每個對象各自持有的獨立空間,對象單方面修改,不會影響其他對象。
public class MyClass {public int a;//實例屬性public static int b;//靜態屬性
}public class MyTest2 {public static void main(String[] args) {//static修飾的變量隨著類的加載而存在,和是否創建對象無關。MyClass.b = 10;System.out.println(MyClass.b);System.out.println("==========================");MyClass c1 = new MyClass();MyClass c2 = new MyClass();System.out.println("c1.b = " + c1.b);System.out.println("c2.b = " + c2.b);System.out.println("==========================");c1.b = 1000;System.out.println("c1.b = " + c1.b);System.out.println("c2.b = " + c2.b);}
}
靜態屬性是整個類共同持有的共享空間(只有一份),任何對象修改靜態屬性,都會影響其他對象對該屬性的訪問。
static修飾的變量隨著類的加載而存在,和是否創建對象無關。
1.3修飾一個方法(靜態方法)
public class MyClass {public int a;public static int b;//由static修飾的靜態方法public static void m1() {//在本類中,可以通過"靜態方法名"訪問m2();System.out.println("m1....");}//由static修飾的靜態方法public static void m2() {System.out.println("m2....");}
}public class MyTest2 {public static void main(String[] args) {//在其他類中,可以通過"類名.靜態方法名"的方式訪問靜態方法MyClass.m1();}
}
關于靜態的注意事項:
靜態方法允許值訪問靜態成員; 想要調用的話:new對象調用
靜態方法不能直接訪問非靜態成員;
靜態方法中不允許使用this或是super關鍵字。
1.4.static修飾成員的訪問特點總結
1.在靜態方法中能直接訪問非靜態成員嘛? 不能想要調用的話:new對象調用 2.在非靜態方法中能直接訪問靜態成員嘛? 能a.同類:直接調用類名調用b.不同類:類名調用3.在靜態方法中能直接訪問靜態成員嘛?能a.同類:直接調用類名調用b.不同類:類名調用4.在非靜態方法中能直接訪問非靜態成員嘛?能a.同類:直接調用new對象調用b.不同類:new對象調用
1.5動態代碼塊和靜態代碼塊
1.5.1動態代碼塊
定義在類中,與屬性和方法處于同一級。
語法:
class 類名 {{//動態代碼塊}
}
創建對象時,觸發動態代碼塊的執行(創建一次,執行一次)。
執行時機:
動態代碼塊和實例屬性的初始化順序,由在類中書寫的順序決定;
代碼塊和屬性的初始化先于構造方法執行。
作用:可為實例屬性賦值,或必要的初始行為。
public class X {public X() {System.out.println("實例屬性");}
}public class MyClass1 {private X x = new X();//動態代碼塊{System.out.println("動態代碼塊");}public MyClass1() {System.out.println("構造方法...");}
}public class MyTest3 {public static void main(String[] args) {MyClass1 c1 = new MyClass1();System.out.println("-------------------------");MyClass1 c2 = new MyClass1();}
}
執行結果
實例屬性
動態代碼塊
構造方法...
-------------------------
實例屬性
動態代碼塊
構造方法...
1.5.2 靜態代碼塊
定義在類中,與屬性和方法處于同一級。
語法:
class 類名 {static {//靜態代碼塊}
}
類加載時,觸發靜態代碼塊的執行(僅一次)。
執行時機:
靜態屬性和靜態代碼塊,二者優先級相同,執行順序由定義順序決定
代碼塊和屬性的初始化先于構造方法執行。
作用:可為靜態屬性賦值,或必要的初始行為。
public class Y {public Y() {System.out.println("靜態屬性");}
}public class MyClass2 {private static Y y = new Y();//靜態代碼塊static {System.out.println("靜態代碼塊");}public MyClass2() {System.out.println("構造方法...");}
}public class MyTest4 {public static void main(String[] args) {MyClass2 c1 = new MyClass2();System.out.println("+++++++++++++++++++++++++++");MyClass2 c2 = new MyClass2();}
}
執行結果
靜態屬性
靜態代碼塊
構造方法...
+++++++++++++++++++++++++++
構造方法...
對象創建過程
public class X {public X() {System.out.println("實例屬性");}
}public class Y {public Y() {System.out.println("靜態屬性");}
}public class MyClass3 {private X x = new X();private static Y y = new Y();//動態代碼塊{System.out.println("動態代碼塊");}//靜態代碼塊static {System.out.println("靜態代碼塊");}public MyClass3() {System.out.println("構造方法...");}
}public class MyTest5 {public static void main(String[] args) {MyClass3 c1 = new MyClass3();System.out.println("==========================");MyClass3 c2 = new MyClass3();}
}
執行結果
靜態屬性
靜態代碼塊
實例屬性
動態代碼塊
構造方法...
==========================
實例屬性
動態代碼塊
構造方法...
1.6帶有繼承的對象創建過程
public class X {public X() {System.out.println("父類實例屬性");}
}public class Y {public Y() {System.out.println("父類靜態屬性");}
}public class M {public M() {System.out.println("子類實例屬性");}
}public class N {public N() {System.out.println("子類靜態屬性");}
}public class SuperClass {private X x = new X();private static Y y = new Y();//動態代碼塊{System.out.println("父類動態代碼塊");}//靜態代碼塊static {System.out.println("父類靜態代碼塊");}public SuperClass() {System.out.println("父類構造方法...");}
}public class SubClass extends SuperClass {private M m = new M();private static N n = new N();//動態代碼塊{System.out.println("子類動態代碼塊");}//靜態代碼塊static {System.out.println("子類靜態代碼塊");}public SubClass() {System.out.println("子類構造方法...");}
}public class MyTest6 {public static void main(String[] args) {SubClass subClass = new SubClass();System.out.println("***************************");SubClass subClass1 = new SubClass();}
}
這里是引用
執行結果
父類靜態屬性
父類靜態代碼塊
子類靜態屬性
子類靜態代碼塊
父類實例屬性
父類動態代碼塊
父類構造方法...
子類實例屬性
子類動態代碼塊
子類構造方法...
***************************
父類實例屬性
父類動態代碼塊
父類構造方法...
子類實例屬性
子類動態代碼塊
子類構造方法...