java中的static修飾詞一直是個貌似很簡單但是很容易出錯的地方,今天特來總結一下,有什麼不對的地方,還望指正
static修飾的變量和方法稱爲類成員,何爲類成員,就是可以直接通過類名去訪問的(一般的方法和變量都要用過類的對象去訪問的);它們從程序開始到程序結束一直都存在,跟C中的全局變量有點像(java中沒有全局變量這一說的),一改全改;static成員是在類被加載時首先被執行的,在整個程序的生命週期中也只會被執行一次,java中最常見的main方法用static修飾也正是這個原因。廢話不多說,用實例來說明問題:
代碼1:
public class Test{
int a;
public static void main(String[] args){
System.out.println(a);
}
}
結果:無法從靜態上下文中引用非靜態 變量 a,靜態方法只能訪問靜態變量;
代碼2:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public int fun(){
int a=0;
return a;
}
}
結果:無法從靜態上下文中引用非靜態 方法 fun(),靜態方法只能訪問靜態的方法
代碼3:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(a);
}
}
結果:輸出0,從這可以知道,static變量不初始化的話,其默認值是0;代碼4:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(new Test().a);
System.out.println(Test.a);
}
}
結果:輸出兩個0,static變量可以通過類名和對象名去訪問,需要指出的是,在實例化一個包含static成員的類時,static變量並沒有被拷貝到對象中去,而是所有的對象都共用類中的static成員。代碼5:
public class Test{
Test test = new Test(){
int a=0;
};
public static void main(String[] args){
System.out.println(a);
}
}
結果:找不到符號a,不能在static方法中訪問實例(對象)中方的成員,原因很簡單,static方法會在實例化一個對象之前執行。代碼6:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(this.a);
}
}
結果:無法從靜態上下文中引用風非靜態變量this,這是一個經常容易犯的錯誤,this表示的是當前的類實例(對象)的引用,在靜態方法和靜態代碼塊中是不能使用this的,因爲static修飾的類成員在實例化之前就可以使用了,而this只能在類已經實例化之後才能使用(super同理)。
代碼7:
public class Test{
static int a;
public static void main(String[] args){
Son son = new Son(){
System.out.println(a);
};
}
}
結果:錯誤:需要<標識符>,錯誤的原因是static成員不能被它所在的類實例所訪問
代碼8:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public static int fun(){
return Son.a;
}
}
static class Son extends Test{ public int a=0; }
結果:此處不允許使用修飾符static,只有內部類才能使用static修飾符。代碼9:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public static int fun(){
return Son.a;
}
static class Son{
public int a=0;
}
}
結果:無法從靜態上下文中引用非靜態變量a,表明a是非靜態的,所以static類的成員不一定是static的。代碼10:
class Test{
public Test(){
System.out.print("1");
}
static{
System.out.print("2");
}
{
System.out.print("3");
}
}
public class Son extends Test{
public Son(){
System.out.print("4");
}
static{
System.out.print("5");
}
{
System.out.print("6");
}
public static void main(String[] args){
new Son();
}
}
結果:253164,表明執行順序依次爲:父類靜態塊,子類靜態塊,父類塊,父類構造函數,子類塊,子類構造函數,這一點也能解釋爲什麼代碼5會出錯,靜態方法會在構造函數之前執行。<pre code_snippet_id="119789" snippet_file_name="blog_20131219_4_5614178">