Java類體中有類方法和實例方法。this
用static修飾的方法。因爲類方法是屬於整個類的,並不屬於類的哪兒個對象,因此類方法的方法體中不能有與類的對象有關的內容。即類方法體有以下限制:線程
1.類方法中不能引用對象變量;對象
2.類方法中不能調用類的對象方法;內存
3.在類方法中不能調使用super,this關鍵字;編譯器
4.類方法不能被覆蓋。編譯
當一個類建立了一個對象後,這個對象就能夠調用該類的方法(對象方法)。變量
1.實例方法中能夠引用對象變量,也能夠引用類變量;引用
2.實例方法中能夠調用類方法;程序
3.對象方法中可使用super,this關鍵字。方法
在類的初始化過程當中,首先加載的是類方法,其次纔是實例方法。
類方法:在該類的字節碼被加載到內存時,就分配了相應的入口地址。從而類方法不只能夠被類建立的任何對象調用執行,也能夠直接經過類名調用,類方法的入口地址直到程序退出時才被取消。類中的類方法不能夠操做實例變量,也不能夠調用實例方法,這是由於在類建立對象以前,實例成員變量尚未分配內存,並且實例方法也沒有入口地址。
實例方法:當類的字節碼文件被加載到內存時,類的實例方法不會被分配入口地址,當該類建立對象後,類中的實例方法才分配入口地址,從而實例方法能夠被類建立的任何對象調用執行。
注意:當咱們建立第一個對象時,類中的實例方法就分配了入口地址,當再建立對象時,再也不分配入口地址,也就是說,方法的入口地址被全部的對象共享,當全部的對象都不存在時,方法的入口地址才被取消。
關於這一點的解釋以下:在建立對象時,實例方法的入口地址被保存在方法區中,而有人會有疑問:方法區不是線程共享的區域麼?對的,由於若是實例方法也隨着實例的增長而增長的話,那麼將消耗很大的內存。爲了保證多個實例的方法入口地址共享一小段內存,且方法中的數據又僅提供給當前實例使用,Java是經過this關鍵字作到的。好比:instance1.instanceMethod(); instance2.instanceMethod(); 由於咱們也知道方法中的局部變量是存儲於方法棧中,而方法棧是線程私有的。因此也就是:共享方法的入口地址,但方法中的數據及局部變量都是私有的。
在傳遞給對象參數的時候,Java 編譯器自動先加上了一個this參數,它表示傳遞的是這個對象引用,雖然他們兩個對象共用一個方法,可是他們的方法中所產生的數據是私有的,這是由於參數被傳進來變成call stack內的entry,而各個對象都有不一樣call stack,因此不會混淆。其實調用每一個非static方法時,Java 編譯器都會自動的先加上當前調用此方法對象的參數,有時候在一個方法調用另外一個方法,這時能夠不用在前面加上this的,由於要傳遞的對象參數就是當前執行這個方法的對象。
總結:
方法入口是同一個,只不過方法內的局部變量以及局部數據(也就是方法中所產生的數據都是私有的)是線程私有的。
方法入口是存放在方法區(線程共享),局部變量是存在方法棧(線程私有)。