一、static修飾的變量習慣稱爲靜態變量,static修飾的方法稱爲靜態方法,static修飾的代碼塊叫作靜態代碼塊。html
1)static變量java
static變量也稱做靜態變量,靜態變量和非靜態變量的區別是:靜態變量被全部的對象所共享,在內存中只有一個副本,它當且僅當在類初次加載時會被初始化。而非靜態變量是對象所擁有的,在建立對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。編程
static成員變量的初始化順序按照定義的順序進行初始化。性能
1 public static String sr ="this is a static variable";
2)static方法字體
static方法通常稱做靜態方法,因爲靜態方法不依賴於任何對象就能夠進行訪問,所以對於靜態方法來講,是沒有this的,由於它不依附於任何對象,既然都沒有對象,就談不上this了。而且因爲這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,由於非靜態成員方法/變量都是必須依賴具體的對象纔可以被調用。優化
1 public static void f(){......};
3)static代碼塊this
static關鍵字還有一個比較關鍵的做用就是 用來造成靜態代碼塊以優化程序性能。static塊能夠置於類中的任何地方,類中能夠有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每一個static塊,而且只會執行一次。spa
1 static{ 2 startDate = Date.valueOf("1946"); 3 endDate = Date.valueOf("1964"); 4 }
參考博客:http://www.cnblogs.com/dolphin0520/p/3799052.html(大字體比較顯眼)htm
二、java的靜態變量也叫作類變量,它開始於類的建立,結束於類的消亡。非靜態變量叫作實例變量,它開始於類的實例的建立,結束於類的實例的消亡。對象
靜態變量被全部實例所共享。
三、java中爲何靜態類能夠直接調用方法?
由於該類的靜態方法是程序啓動時自動放在內存中了的,是屬於程序的公共內存(但只能訪問),而類名在這裏你能夠理解爲命名空間。先通俗的分析下,咱們把類看做是一個房子。房子裏面有傢俱,桌椅板凳之類的,房子裏面還有人。
房子裏面全部的人都應該是共有一套傢俱的。也就是說,這些傢俱是惟一的,若是某個傢俱壞了,那麼你們都用不了。
咱們再看一看定義,java的靜態變量也叫作類變量,它開始於類的建立,結束於類的消亡。非靜態變量叫作實例變量,它開始於類的實例的建立,結束語類的實例的消亡。靜態變量被全部實例所共享。也就是如上面的例子,座椅板凳是類變量,它們是在房子被建好了以後就被添加放置進來,並且基本都是惟一的。人就至關於實例,每一個人都能用這些傢俱,可是若是傢俱一旦損壞,那就是壞了,或者你把某一個傢俱搬走,那麼全部的人都用不了這個傢俱,房子裏也不存在這個傢俱了。
可是房子裏能夠進不少人,能夠進張三,也能夠進李四。因此這些人就是類的實例對象,他們身上穿的衣服就能夠叫作實例變量。
若是一個類中有靜態變量的話,程序首先會把該靜態變量加載進內存中,也就是在堆中開闢一個區域專門存放。之後無論你new多少個類的對象,該靜態變量永遠都是在那裏的。也就是說,靜態變量在類的初始化一次後,系統就不會爲該變量開闢新的內存空間。而每new一個類的對象,系統就會從新在
堆內存中開闢一個新空間來存放該類的實例對象,而且棧中也會有一個新的引用變量去指向它。
靜態方法也是相似,可是有一點要強調,靜態方法中不能調用非靜態方法。由於被static修飾的方法會首先被Classloader對象先加載進內存,而這個時候可能其它的非靜態方法或者變量尚未被加載進來。就比如我如今想作包子,如今麪粉被static修飾,首先已經拿到你身邊,但是由於包子餡不是static修飾的,因此可能包子餡兒還沒運過來,你說怎麼作的出包子呢。
被static修飾過的都是隨着類的初始化後就產生了,在堆內存中都有一塊專門的區域來存放,因此只須要類名點方法名或者變量名便可。而非靜態的就必須經過類的對象去調相應的。就像是你想要紅色的衣服,你必須是從穿紅色的衣服的人的身上拿過來才行,因此你必須找到穿紅色衣服的人,也就是類的實例對象,而你若是要去找一個桌子,而桌子就在房間裏擺着,你只要進到房間裏直接走過去拿來就能夠了
四、static關鍵字的用途
在《Java編程思想》P86頁有這樣一段話:
「static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是能夠的。並且能夠在沒有建立任何對象的前提下,僅僅經過類自己來調用static方法。這實際上正是static方法的主要用途。」
方便在沒有建立對象的狀況下來進行調用(方法/變量)。
其實若是非要在靜態方法中調用非靜態方法,也是有辦法解決的。
1 public class StaticMethodTest{ 2 void NonStaticMethod(){ 3 System.out.println("This is copy 別人的代碼"); 4 } 5 //NonStaticMethod()是一個非靜態的方法 6 7 static void StaticMethod(StaticMethodTest s){ 8 System.out.println("太懶了,不想寫."); 9 s.NonStaticMethod(); 10 } 11 /***咱們在StaticMethod()方法中調用了NonStaticMethod()方法,在這裏咱們作了一個折中的辦法,在靜態方法加載的時候,咱們並不能建立對象實例來用於調用非靜態方法,可是咱們在這裏只是建立了一個引用並無建立實例。因此沒有違反java的語法,因此編譯能夠經過,當有調用這個靜態方法時,外部會傳進來一個實例的引用,而後經過實例來調用方法NonStaticMethod()。*********/ 12 13 public static void main(String[] args) { 14 StaticMethodTest sObj=new StaticMethodTest();//建立一個實例 15 StaticMethod(sObj); //調用靜態方法,並傳進去一個實例的引用。 16 } 17 }
注意:java的引用能夠單獨存在,不必定非要依存於實例。
1 String sr;//建立一個名字爲sr的引用 2 3 String mm="sm";//建立一個引用爲mm的實例 4 5 sr=mm;//將mm對應的引用賦值給sr,這裏只是複製引用,並無操縱sm。
5.static關鍵字會改變類中成員的訪問權限嗎?
有些初學的朋友會將java中的static與C/C++中的static關鍵字的功能混淆了。在這裏只須要記住一點:與C/C++中的static不一樣,Java中的static關鍵字不會影響到變量或者方法的做用域。在Java中可以影響到訪問權限的只有private、public、protected(包括包訪問權限)這幾個關鍵字。
6.能經過this訪問靜態成員變量嗎?
1 public class Main { 2 static int value = 33; 3 4 public static void main(String[] args) throws Exception{ 5 new Main().printValue(); 6 } 7 8 private void printValue(){ 9 int value = 3; 10 System.out.println(this.value); 11 } 12 } 13 14 //結果是33
這裏面主要考察對this和static的理解。this表明什麼?this表明當前對象,那麼經過new Main()來調用printValue的話,當前對象就是經過new Main()生成的對象。而static變量是被對象所享有的,所以在printValue中的this.value的值毫無疑問是33。在printValue方法內部的value是局部變量,根本不可能與this關聯,因此輸出結果是33。在這裏永遠要記住一點:靜態成員變量雖然獨立於對象,可是不表明不能夠經過對象去訪問,全部的靜態方法和靜態變量均可以經過對象訪問(只要訪問權限足夠)。
3.static能做用於局部變量麼?
在C/C++中static是能夠做用域局部變量的,可是在Java中切記:static是不容許用來修飾局部變量。不要問爲何,這是Java語法的規定。