2011-01-31 47 views
4

所有瘋狂的Java範圍規則正在使我的頭腦旋轉,而廢話無助於事情的發展。到目前爲止,我所使用的所有編程語言,無論是詞法範圍還是近似值,都沒有任何訪問修飾符,即內部東西捕獲外部東西,只要內部東西存在就可以訪問外部東西。Java範圍規則和內部類

那麼,我如何理解Java中內部類的範圍規則呢?他們是否可以訪問在外部類中聲明的變量,或者是否有一些奇怪的邊緣情況需要擔心,因爲所有的東西都是浮動的?

+9

請(1)調低和(2)澄清你的問題。你所問的'瘋狂的Java範圍規則'與C++中的'詞法範圍'相同。你將不得不解釋你的意思是「公共靜態無效」的廢話:這是另一個功能,它也存在於C++中。而「公共靜態私人」的東西「並不存在:這僅僅是一個矛盾。 – EJP 2011-01-31 06:06:32

+1

可以肯定的是,OP來自腳本語言背景,具有真正的詞法範圍(例如JavaScript,Ruby),並且不重視修飾符關鍵字。只是說。 – ide 2011-01-31 06:11:49

回答

17

靜態嵌套類酷似外部類不同之處在於它們可以訪問外部類的所有成員,而不管接入限定符。它們除了外部類的任何實例之外都存在,因此需要引用實例才能訪問外部類的任何實例變量或非靜態方法。

非靜態嵌套類(稱爲內部類)僅在外部類的實例的上下文中出現。構建時,他們會自動生成第二個this字段,您可以使用語法Outer.this從內部類訪問該字段。內部類的每個實例都由外部類的單個實例包圍。同樣,靜態嵌套類的所有訪問權限都適用於內部類。但由於它們已經有了一個可用外部類的實例,所以它們可以自動訪問外部類的實例變量和方法。

對於內部類和訪問說明符的一個很好的(也是非常詳細的)討論,您可以通讀Inner Class Specification。它還描述了嵌套類如何訪問外部類的成員(private)。一個溫和的閱讀是Nested Classes tutorial

閒談一邊:假設你有這樣的階級結構:

public class O { 
    public O() { ... } 

    public class I { // an inner class 
     public I() { ... } 
     ... 
    } 
    ... 
} 

,你已經創造了O一個實例:

O outer = new O(); 

現在假設你想創建的實例O.I。您不能僅僅使用new O.I(),因爲需要將I的新實例包含在O的特定實例中。爲此,Java提供的語法如下:

O.I inner = outer.new O.I(); 

然後inner屆時將有第二this字段設置爲參考outer

請注意,此「合格的new運算符」語法僅用於內部類;如果I是嵌套類static,那將是沒有必要的(實際上是一個錯誤)。

  你經常會遇到短語「靜態內部類」(包括令人尷尬的,在這個答案的早期版本)。這是不正確的術語。在Java中,「內部類」特別是不嵌套的類。

3

你有者區分:

  • 靜態內部類可以訪問他們的聲明之外的所有靜態成員。
  • 實例內部類可以訪問他們的聲明之外的所有集體成員,以及在功能最後場他們在聲明。

有想法,一個非靜態內部類也有一個隱藏的與外部類的實例一起變量,以訪問那裏的成員。並且所有引用的最終字段(因此它們必須是最終的)在實例化內部類時被複制到其他隱藏成員變量的內部類中。

實施例:

public void doStuff(final int a, int b) { 
    final int c; // Can be referenced 
    int d;  // Cannot be referenced, not final 

    executer.execute(new Runnable() { 
     public void run() { 
      System.out.println("a: "+a+" c: "+c); 
     } 
    } 

    b++; // Not final, not referencable 
    System.out.println(b); 
} 
3

我不知道是否有幫助,但是從java tutorials

靜態嵌套類

與類方法和變量,靜態嵌套類與它相關聯的外類。像靜態類方法一樣,靜態嵌套類不能直接引用其封閉類中定義的實例變量或方法 - 它只能通過對象引用來使用它們。 注意:靜態嵌套類與其外部類(和其他類)的實例成員交互,就像任何其他頂級類一樣。實際上,爲了方便打包,靜態嵌套類在行爲上是嵌套在另一個頂級類中的頂級類。

內部類 [非靜態嵌套類?]

與實例方法和變量,一個內部類與它的外圍類和的實例相關聯具有與對象的方法和字段的直接訪問。另外,因爲內部類與一個實例相關聯,所以它不能自己定義任何靜態成員。

您應該檢查the java tutorial on nested classes

0

規則內部類

  1. 通過內部類訪問外部類
  2. 內部類不能由外類訪問
  3. 內類成員只使用的方法和構件在類內只訪問充實的信息
-1

方法範圍內部分類ses: - 只能訪問外部類的最終成員。