面向对象:9、static关键字
static關鍵字
- 一、static修飾變量
- 二、static修飾方法
- 三、代碼塊
一、static修飾變量
1.static:靜態的
2.static可以用來修飾:屬性、方法、代碼塊、內部類
在類中,使用static修飾的成員變量,就是靜態變量,反之為非靜態變量。
靜態變量和非靜態變量的區別
靜態變量(類變量):我們創建了類的多個對象,多個對象共享同一個靜態變量。當通過某一個對象修改靜態變量時,會導致其他對象調用此靜態變量時,是修改過了的。
實例變量(非靜態變量):我們創建了類的多個對象,每個對象都獨立的擁有一套類中的非靜態屬性。當修改其中一個對象中的非靜態屬性時,不會導致其他對象中同樣的屬性值的修改。
靜態變量屬于類的,"可以"使用類名來訪問,非靜態變量是屬于對象的,"必須"使用對象來訪問
因為在加載類的過程中為靜態變量分配內存,實例變量在創建對象時分配內存,所以靜態變量可以使用類名來直接訪問,而不需要使用對象來訪問
public class Student{private static int age;private double score;public static void main(String[] args) {Student s = new Student();//推薦使用類名訪問靜態成員System.out.println(Student.age);System.out.println(s.age);System.out.println(s.score);} }其他說明
- 靜態變量隨著類的加載而加載??梢酝ㄟ^"類.靜態變量"的方式進行調用
- 靜態變量的加載要早于對象的創建
- 由于類只會加載一次,則靜態變量在內存中也只會存在一份:存在方法區的靜態域中
| 類 | √ | × |
| 對象 | √ | √ |
- 靜態屬性舉例:System.out; Math.PI
二、static修飾方法
在類中,使用static修飾的成員方法,就是靜態方法,反之為非靜態方法
靜態方法和非靜態方法的區別
靜態方法是屬于類的,"可以"使用類名來調用,非靜態方法是屬于對象的,"必須"使用對象來調用.
靜態方法"不可以"直接訪問類中的非靜態變量和非靜態方法,但是"可以"直接訪問類中的靜態變量和靜態方法
注意:
- this和super在類中屬于非靜態的變量.(靜態方法中不能使用)
- 關于靜態屬性和靜態方法的使用,都從生命周期的角度去理解
非靜態方法"可以"直接訪問類中的非靜態變量和非靜態方法,也"可以"直接訪問類中的靜態變量和靜態方法
public class Student{private static int count;private int num;public void run(){}public static void go(){}public void test(){//編譯通過System.out.println(count);go();//編譯通過System.out.println(num);run();} }| 類 | √ | × |
| 對象 | √ | √ |
main方法
三、代碼塊
1、什么是代碼塊
public class Person {{//代碼塊(匿名代碼塊)}static{//靜態代碼塊} }代碼塊類似于方法體,內部可以有很多方法中有的東西
2、代碼塊的作用:用來初始化類、對象
3、代碼塊如果有修飾的話,只能使用static
4、分類:靜態代碼塊 vs 非靜態代碼塊
靜態代碼塊
-
內部可以有輸出語句
-
隨著類的加載而執行,而且只執行一次
-
作用:初始化類的信息
-
如果一個類中定義了多個靜態代碼塊,則按照聲明的先后順序執行
-
靜態代碼塊的執行要優先于非靜態代碼塊的執行
-
靜態代碼塊內只能調用靜態的屬性、靜態的方法,不能調用非靜態的結構
非靜態代碼塊
- 內部可以有輸出語句
- 隨著對象的創建而執行
- 每創建一個對象,就執行一次非靜態代碼塊
- 作用:可以在創建對象時,對對象的屬性等進行初始化
- 如果一個類中定義了多個非靜態代碼塊,需要按照聲明的先后順序執行
- 非靜態代碼塊內可以調用靜態的屬性、靜態的方法,或非靜態的屬性、非靜態的方法
5、代碼示例
package com.hsy.staticTest.block;public class BlockTest {public static void main(String[] args) {String desc = Person.desc;System.out.println(desc);Person p1 = new Person();Person p2 = new Person();System.out.println(p1.age);Person.info();} }class Person{//屬性String name;int age;static String desc = "我是一個人";//構造器public Person(){}public Person(String name,int age){this.name = name;this.age = age;}//非static的代碼塊{System.out.println("hello, block - 2");}{System.out.println("hello, block - 1");//調用非靜態結構age = 1;eat();//調用靜態結構desc = "我是一個愛學習的人1";info();}//static的代碼塊static{System.out.println("hello,static block-2");}static{System.out.println("hello,static block-1");//調用靜態結構desc = "我是一個愛學習的人";info();//不可以調用非靜態結構 // eat(); // name = "Tom";}//方法public void eat(){System.out.println("吃飯");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}public static void info(){System.out.println("我是一個快樂的人!");}}6、小練習
package com.hsy.staticTest; //總結:由父及子,靜態先行 class Root{static{System.out.println("Root的靜態初始化塊");}{System.out.println("Root的普通初始化塊");}public Root(){super();System.out.println("Root的無參數的構造器");} } class Mid extends Root{static{System.out.println("Mid的靜態初始化塊");}{System.out.println("Mid的普通初始化塊");}public Mid(){super();System.out.println("Mid的無參數的構造器");}public Mid(String msg){//通過this調用同一類中重載的構造器this();System.out.println("Mid的帶參數構造器,其參數值:"+ msg);} } class Leaf extends Mid{static{System.out.println("Leaf的靜態初始化塊");}{System.out.println("Leaf的普通初始化塊");} public Leaf(){//通過super調用父類中有一個字符串參數的構造器super("hsy");System.out.println("Leaf的構造器");} } public class LeafTest{public static void main(String[] args){new Leaf(); System.out.println();new Leaf();} }總結
以上是生活随笔為你收集整理的面向对象:9、static关键字的全部內容,希望文章能夠幫你解決所遇到的問題。