爲什麼不能從靜態的方法裏面調用非靜態方法,或變量?

 

   程序最終都將在內存中執行,變量只有在內存中佔有一席之地時才能被訪問。

類的靜態成員(變量和方法)屬於類本身,在類加載的時候就會分配內存,可以通過類名直接去訪問;非靜態成員(變量和方法)屬於類的對象,所以只有在類的對象產生(創建類的實例)時纔會分配內存,然後通過類的對象(實例)去訪問。

在一個類的靜態成員中去訪問其非靜態成員之所以會出錯是因爲在類的非靜態成員不存在的時候類的靜態成員就已經存在了,訪問一個內存中不存在的東西當然會出錯:

而類又是在什麼時候加載的呢?

    由引導類加載器負責加載的核心類比如 String 類在 JVM 啓動時(main 方法開始執行前)就會被加載,其它類在使用前(new 它對象或調用其靜態方法訪問靜態域等等前)會被動態加載,要注意的是子類被加載前它的所有超類要根據由父到子的順序被逐一加載。

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);
    }
}
public class TestStatic
{
   
public static void main(String args[])
    {
        System.out.println(
"b.a="+B1.a);
        System.out.println(
"b.a="+A1.a);
       
new B1().print();
    }
}

就這段代碼說一下.

就你上面的代碼說一下:
當你在doc環境下輸入:
java TestStatic時,
虛擬機會先加載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()方法執行完,整個程序退出。

發佈了22 篇原創文章 · 獲贊 10 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章