簡體   English   中英

Java 新關鍵字與 static 內部 class

[英]Java new keyword with static inner class

我知道以前有人問過這個問題,但大多是關於某個庫的。 給出的答案並沒有真正向我解釋發生了什么。

這就是為什么我在這里設置了一個非常簡單的測試場景,並試圖擺弄它,但仍然有一些問號! 在線Java示例

簡單代碼由兩個文件組成:

Main.java

public class Main
{
    public static void main(String[] args) {
        // this works, and inner1 and inner2 seem to be new instances
        Outer.Inner inner1 = new Outer.Inner();
        Outer.Inner inner2 = new Outer.Inner();
        inner1.setName("Mario");
        inner1.say();
        inner2.setName("Luigi");
        inner2.say();

        // if Inner is not a public static class this gives this error:
        // error: an enclosing instance that contains Outer.InnerNoStatic is required
        Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
    }
}

Outer.java

public class Outer {
    public static class Inner {
        private String name;

        public void say() {
            System.out.println("Hi " + name);
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public class InnerNoStatic {
        public void say() {
            System.out.println("Hi from InnerNoStatic");
        }
    }
}

所以看起來即使Inner class 是用 static 聲明的,我們還是創建了兩個新實例,稱為 inner1 和 inner2。 那為什么叫static呢?

反過來,如果我刪除 static,就像在InnerNoStatic中一樣,我將如何 go 獲取該 class 的實例?

所以看起來即使內部 class 是用 static 聲明的,我們還是創建了兩個新實例,稱為 inner1 和 inner2。 那為什么叫static呢?

“靜態”內部 class 的對象不綁定到其封閉 class 的對象,與非“靜態”內部類相反。 Having a "static" inner class instead of moving that class to the "top level" is a handy way of signalling to a user that objects of that inner class have not much use separate from the outer class, similar to eg Map.Entry .

反過來,如果我刪除 static,就像在 InnerNoStatic 中一樣,我將如何 go 獲取該 class 的實例?

例如

public class Outer {

  private InnerNoStatic innerNoStatic = new InnerNoStatic();

  public InnerNoStatic getInnerNoStatic () {
    return innerNoStatic;
  }
  // ...

Outer.InnerNoStatic innerNoStatic = new Outer().getInnerNoStatic();

所以看起來即使內部 class 是用 static 聲明的,我們還是創建了兩個新實例,稱為 inner1 和 inner2。 那為什么叫static呢?

static意味着嵌套的 class 更加獨立。 它的設計主要是為了增加封裝性、可讀性、可維護性,它是邏輯分組類的好方法。

反過來,如果我刪除 static,就像在 InnerNoStatic 中一樣,我將如何 go 獲取該 class 的實例?

語法有點不同,因為您需要一個Outer實例。

Outer.InnerNoStatic inner3 = new Outer(). new InnerNoStatic();

static在這里規定了如何相對於Outer使用InnerInnerNoStatic

因為InnerOuter中是 static ,所以它不綁定到Outer的任何特定實例(與往常一樣,static 成員屬於該類的 class 實例,而不是任何特定實例)。 這解釋了它是如何編譯的:

Outer.Inner inner1 = new Outer.Inner();

然而, InnerNoStatic是一個實例成員(即:如果它不是 static,則它與給定成員綁定)。 這就解釋了為什么編譯器會在這里引發錯誤:

Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();

因為InnerNoStatic必須綁定到Outer的實例,所以您需要使用這樣的實例來創建inner3

Outer.InnerNoStatic inner3 = new Outer().new InnerNoStatic(); //note the calls

您也可以使用現有實例。

Outer outer = new Outer();
Outer.InnerNoStatic inner3 = outer.new InnerNoStatic();

在這兩種情況下,都使用Outer實例來構建InnerNoStatic實例(只是沒有變量指向使用new Outer().new InnerNoStatic()創建的Outer object)


注意:很容易混淆new Outer.Inner(); 使用new Outer().new Inner(); . 這些不是做同樣的事情(前者中的“Outer”基本上是扮演命名空間的角色,而后者中的new Outer()是創建一個Outer對象)。 也就是說,前者調用了一個構造函數( Inner() ),而后者調用了兩個構造函數( Outer()Inner() )。

非靜態內部類總是引用對應的外部 class。 因此,這樣的 class 只能由 Outer class 實例化。

相反,static 內部 class 沒有參考外部 class 並且可以由任何其他 ZA8CFDE6331.49EB26AC96F 允許的可見性創建這與 static 方法的行為非常相似,不需要調用對象實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM