2016-06-26 23 views
-1

當我們執行前向引用方法時,編譯器中發生了什麼?它如何分配未聲明的另一個變量的值?我們可以使用裏面的方法嗎?但爲什麼我們不能在靜態塊中使用變量?例如,爲什麼只能在方法中使用前向引用

public class Forward { 

    static int i = test(); 

    static int test() { 

     System.out.println(j); 
     j = 20; 
     return j; 
    } 

    static { 
     System.out.println(j); 
     j = 20; 
    } 
    static int j; 
} 

如果我們直接分配像值:

int i = j; 
int j = 10; 

爲什麼這個代碼不能編譯?如何只能用方法?編譯器如何在內部編譯前向引用?聲明是否首先發生在所有變量和初始化中,一次一個或一個接一個地發生?詳細解釋它。

+3

「詳細講解」 你看[JLS 8.8.3](https://docs.oracle.com/javase/specs/jls /se8/html/jls-8.html#jls-8.3.3)? –

+0

感謝您的回覆。我讀過它,但我無法清楚地瞭解這個流程。使用前向引用時是否有任何規則需要遵循。你能詳細解釋一下嗎? – Dhivakar

回答

1

JLS Section 8.3.3指出,4個標準必須全部滿足,如果一個靜態變量的正向使用將被視爲一個編譯時錯誤:,

The declaration of a class variable in a class or interface C appears textually after a use of the class variable;

換句話說顯然,它必須是一個「前進聲明「:你使用它,你聲明之前:

// Maybe not OK to use j here. 

static int j; 

// OK to use j here. 

The use is a simple name in either a class variable initializer of C or a static initializer of C;

您可以向前參考變量,如果您符合它的名字:

static { 
    System.out.println(j);      // Error on this line... 
    System.out.println(Forward.j);    // ...but not this line... 
    System.out.println(org.whatever.Forward.j); // ...or this line... 
} 
static int j; 

此標準僅適用於變量或靜態初始化程序。這回答了爲什麼在引用方法中的靜態變量時沒有得到編譯器錯誤的具體問題。

不過,我們只是完成的事情了......

The use is not on the left hand side of an assignment;

注意在此代碼:

static { 
    System.out.println(j); // Error on this line... 
    j = 20;     // ...but not this line. 
} 
static int j; 

你不能做任何東西,除了指定的變量,即使你顛倒順序(不能分配然後打印)。

C is the innermost class or interface enclosing the use.

下面的代碼就可以了:

class Forward { 
    static class Inner { 
    static { 
     System.out.println(j); 
    } 
    } 

    static int j; 
} 
相關問題