package Test;函數
public class TestStatic
{
public static void main(String args[])
{
System.out.println("b1.a="+B1.a);
System.out.println("a1.a="+A1.a);
new B1().print();
TestStatic sObj=new TestStatic();
StaticMethod(sObj); //在主函數中能夠直接調用靜態方法
}
void NonStaticMethod(){
System.out.println("This is a non-sataic method.");
}
static void StaticMethod(TestStatic s){
System.out.println("This is a 靜態 method.");
s.NonStaticMethod();
// this.s=s;
}
}this
class A1
{
public static int a=5;
}
class B1 extends A1
{
public static int a=8;
void print(){
System.out.println(super.a);
System.out.println(a);
}
}spa
輸出:對象
b1.a=8
a1.a=5
5
8
This is a 靜態 method.
This is a non-sataic method.內存
虛擬機會先加載TestStatic類,此時虛擬機會先看看TestStatic類有沒有靜態的字段,
上例中沒有,直接執行main方法。
main方法中第一句代碼是打印B1.a,
虛擬機便會去找類B1,找到類B1時,虛擬機發現B1的父親是A1,
因而父親優先,先加載A1,
一樣,在加載A1時,會看看A1中有什麼靜態的東西,有,
static int a = 5;
a是靜態的,先加載,當把靜態的字段加載完後,一個類就算加載完了,
因此A1已經加載完畢,之後不用再加載了。
父親加載完了,輪到B1了,一樣先看看裏面有什麼靜態的字段,有,
static int a = 8;
此時B1也加載完畢了。
第一條打印語句到此時也執行完畢了,
輪到第二條打印語句了。
當執行new B1().print();這句時,
會發生動態綁定,
此時會有一個表明B1對象的this對象傳遞給print()方法,
因此print()方法中的
System.out.println(a);
實際上是,
System.out.println(this.a);
會打印出一個8出來。
至於super.a就簡單了,
打印父類中的a,
結果是5.
到此,main()方法執行完,整個程序退出。編譯器
一、 在靜態方法中是不能使用this預約義對象引用的,即便其後邊所操做的也是靜態成員也不行.
由於this表明的是調用這個函數的對象的引用,而靜態方法是屬於類的,不屬於對象,靜態方法成功加載後,對象還不必定存在 ,super的用法跟this相似,this表明對本類對象的引用,指向本類已經建立的對象;而super表明對父類對象的引用,指向父類對象;.靜態優先於對象存在;
由於靜態優先於對象存在,因此方法被靜態修飾以後方法先存在,而方法裏面要用到super指向的父類對象,可是所需的父類引用對象晚於該方法出現,也就是super所指向的對象沒有,固然就會出錯。綜上,靜態方法中不能夠出現super和this關鍵字。虛擬機
二、this和super是屬於對象範疇的東西,而靜態方法是屬於類範疇的東西
全部的成員方法,都有一個默認的的參數this(即便是無參的方法),只要是成員方法,編譯器就會給你加上this這個參數如:
Class A中
void method1(){}其實是這樣的--------> void method1(A this)
void method2(int x){}其實是這樣的--------> void method2(A this, int x)
而靜態方法與對象無關,根本不能把對象的引用傳到方法中,因此不能用this。編譯
三、在一個類中定義一個方法爲static,則爲靜態方法,那就是說,無需本類的對象便可調用此方法,調用一個靜態方法就是「類名.方法名」,既然"無需本類的對象便可調用靜態方法",而this和super關鍵字都是用於本類對象的-----調用靜態方法無需本類的對象這句話很清楚代表:靜態方法中不能用this和super關鍵字, 靜態方法是存放在內存中的數據段裏,this和super調用的是堆空間裏的應用對象不能調用數據段區域裏的數據, 靜態方法和靜態類不屬於單個對象,而是類的全部對象共享使用,而this表明當前對象。 所以靜態方法中不能用this和super關鍵字。class
再看下面的例子:變量
package Test;
public class StaticMethod {
//定義一個非靜態方法
public void callMe2()
{
System.out.println("This is a nonstatic method");
}
//定義一個靜態方法
public static void callMe() //靜態方法
{
System.out.println("This is a static method");
}
public void Test(){
callMe(); //正確,能夠直接調用訪問本類靜態方法
callMe2(); //正確,能夠直接調用訪問本類非靜態方法
StaticMethod.callMe(); //調用靜態對象無需建立對象,能夠直接用「類名。方法名」訪問
StaticMethod mob=new StaticMethod();
mob.callMe2(); //調用非靜態的使用「對象。方法名」訪問
}
public static void main(String[] args){
StaticMethod.callMe(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,在靜態方法中不能調用非靜態的方法和引用非靜態的成員變量
callMe(); //正確,能夠直接調用訪問本類靜態方法
//callMe2(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,因此不能直接訪問callMe2();由於callMe2()是非靜態的。
StaticMethod oa=new StaticMethod();
oa.Test(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,Test是非靜態的,儘管Test內部又調用了靜態的CallMe()
}
}
class Run{ public void RunTest(){ // callMe(); //錯誤 // callMe2(); //錯誤 StaticMethod.callMe(); //調用靜態對象無需建立對象,能夠直接用「類名。方法名」訪問 //StaticMethod.callMe2(); //錯誤 StaticMethod ob=new StaticMethod();//調用非靜態對象要先實例化對象 ob.callMe2(); //調用非靜態的使用「對象。方法名」訪問 } public static void Run_main(String[] args){ System.out.println("RunTest"); StaticMethod.callMe(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,在靜態方法中不能調用非靜態的方法和引用非靜態的成員變量 //StaticMethod.callMe2(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,因此不能直接訪問callMe2();由於callMe2()是非靜態的。 StaticMethod oa=new StaticMethod(); oa.callMe(); //調用靜態對象無需建立對象,能夠直接用「類名。方法名」訪問,也可使用「對象。方法名」訪問 oa.callMe2(); //調用非靜態的使用「對象。方法名」訪問 oa.Test(); //靜態方法在訪問本類的成員時,只容許訪問靜態方法,Test是非靜態的,儘管Test內部又調用了靜態的CallMe() } }