static關鍵字算是Java中比較複雜的關鍵字之一,它能夠修飾變量、方法、類以及代碼塊。下面將介紹static的具體使用。而且擴展介紹關於程序入口函數public static void main(String[] args)
的一些知識。html
在《Java編程思想》中對static的描述有這樣的一句話:java
static方法就是沒有this的方法。在static的方法內部不能調用非靜態方法,反過來到是能夠的。並且能夠在沒有建立任何對象的前提下,僅僅經過類自己來調用static方法。編程
這最後一句即是引入static主要的用途,免去建立類對象的開銷就能夠調用類中的方法,能夠說是十分誘人。函數
private static int num;
變量num能夠稱爲靜態變量也能夠稱爲類變量。 static修飾屬性只能修飾類屬性,不能夠修飾局部變量,如方法中的定義的屬性。Java中規定如此。 Java中的static和C++中的static含義是不同的,C++中的static修飾的變量是全局變量,而Java中沒有全局變量的概念,在Java中使用static修飾的類屬性是存放在方法區
的,爲該類<b>全部對象共享的變量,與具體某個對象沒有關係</b>。this
<b>static屬性和非static屬性的區別</b>主要有兩點:①在內存區域的保存位置不一樣,static屬性存放在方法區,非static屬性存放在堆棧區。②static屬性是屬於類對象的公共屬性,能夠在沒有實例化對象的前提下使用類名.靜態屬性名
的方式訪問;而非static屬性則須要使用對象進行訪問。<br>spa
<b>關於何時該使用static屬性?</b><br> 須要進行描述共享信息的屬性而且該屬性不須要重複開闢內存空間並且便於修改,則使用static進行修飾該變量。其他狀況,不建議使用static修飾變量。命令行
public static void printNumberOfStudent(){ ... }
被static修飾的方法叫作靜態方法。靜態方法同靜態變量同樣能夠直接使用類名稱.靜態方法名
調用。如果<u>使用類名調用靜態方法須要知足該方法不是private</u>。在非靜態方法中是可使用this訪問靜態變量。<br>code
在使用靜態方法時須要注意兩點:<br>htm
<u>靜態方法中是不存在this的。</u>由於this是指向當前對象的,靜態方法是與類相關的,與對象無關,不存在對象調用問題。通常直接使用類名.靜態方法名
進行訪問對象
<u>靜態方法內部只能直接調用靜態方法和靜態成員。</u>調用普通方法會報錯,在普通方法中能夠調用靜態方法。 由於普通方法通常會將對象做爲隱藏實參傳入並用this指向,在沒有建立對象時,普通方法中就不存在this,調用包含普通方法的靜態方法就會報錯!
在程序編寫中能夠直接使用{...}
定義一段語句塊,這個語句塊就是代碼塊,使用static修飾的語句塊就叫作靜態代碼塊。<br> 觀察下面程序的結果,分析靜態塊在程序中的執行順序
public class A { A(){ System.out.println("A constructor"); } static { System.out.println("A's static block"); } } public class B extends A{ B(){ System.out.println("B constructor"); } static { System.out.println("B's static block"); } } public class StaticBlock { public static void main(String[] args) { B objb = new B(); } } /*output A's static block B's static block A constructor B constructor */
能夠看出<b>靜態代碼塊的執行順序優先於構造函數</b>,在程序執行時,會先找到main入口,而後準備加載類B,發現B有父類A,因而先去加載A,靜態代碼塊就是在類加載的時候執行的。在靜態塊執行完後,就會去執行構造函數。<br>
靜態塊由於在構造函數以前執行,因此<b>經常使用來初始化靜態變量</b>。
public class Student { private static int numOfStu; private String name; private int age; static { numOfStu = 0; } public Student(String name, int age) { this.name = name; this.age = age; numOfStu++; } }
<b>靜態代碼塊能夠在類的任意位置定義</b>(方法中不能夠),不會影響其優先於構造函數執行的順序。可是多個靜態塊的執行順序會依據其聲明的先後執行。<br>
public class Student { private static int numOfStu; private String name; private int age; static { numOfStu = 0; System.out.println("first sttaic block"); } public Student(String name, int age) { this.name = name; this.age = age; numOfStu++; } static { System.out.println("second sttaic block"); } public static void main(String[] args) { Student stu1 = new Student("sakura",20); } } /* output: first sttaic block second sttaic block */
內部類顧名思義就是定義在一個類中的類。使用static定義的屬性或者方法是不受類實例化對象的控制的,因此,若是內部類被static修飾,是不會受到外部類實例化對象控制。此時,<b>內部類就相等於變成了一個外部類,而且只能訪問外部類中的static屬性或者方法</b>。關於內部類,後面會詳細介紹。
class Test{ ... public static void main(String[] args){ ... } }
public static void main(String[] args)
做爲Java程序的入口方法,Java虛擬機在運行程序時,會首先查找main()方法。該方法中各個修飾符的做用以下:
java Test
是調用Test.main主方法)。如此看被static修飾的主函數,這樣的好處可能就是:不用建立當前類的對象就能夠調用,節省空間。因爲public和static沒有前後順序關係,因此下面的定義也是合理的
static public void main(String[] args)
也能夠將main()方法定義爲final的
public static final void main(String[] args)
也可使用synchronized關鍵字來修飾
static public synchronized void main(String[] args)
可是無論使用哪一種方式定義,都須要保證main()方法的返回值爲void,而且有static和public關鍵字修飾。由於main()方法做爲程序的入口,所以不能使用abstract關鍵字來修飾!
雖然每一個類中均可以定義main()方法,可是隻有與文件名相同的用public修飾的類中的main()方法才能做爲整個程序的入口方法。以下所示:建立一個名爲Test.java的文件
class T{ public static void main(String[] args){ System.out.println("T main"); } } public class Test{ // 程序入口函數 public static void main(String[] args){ System.out.println("Test main"); } } /* output: Test main */
介紹了Java中static關鍵字的基礎應用:修飾變量、方法等。Java中還能夠利用static關鍵字實現單例模式
,這些後面介紹。
參考:《Java編程思想》第四版
原文出處:https://www.cnblogs.com/myworld7/p/10052245.html