簡體   English   中英

為什么嵌套類在Java和C#之間表現不同?

[英]Why nested classes behave differently between Java and C#?

我不明白為什么Java中出現以下代碼錯誤:

public abstract class TestClass
{
    private final int data;

    protected TestClass(int data) { this.data = data; }

    public final class InnerClass extends TestClass
    {
    private InnerClass(int data) { super(data); }

    public static final TestClass CONSTANT = new InnerClass(5);
    }
}

錯誤發生在public static final TestClass CONSTANT = new InnerClass(5); 部分。 錯誤是:

我:\\ Documents \\ NetBeansProjects \\ TestingGround \\ src \\ testingground \\ TestClass.java:22:error:非靜態變量這不能從靜態上下文引用public static final TestClass CONSTANT = new InnerClass(5); ^ I:\\ Documents \\ NetBeansProjects \\ TestingGround \\ src \\ testingground \\ TestClass.java:22:error:內部類中的非法靜態聲明TestClass.InnerClass public static final TestClass CONSTANT = new InnerClass(5); ^ modifier'static'僅允許在常量變量聲明2中出錯

如果我嘗試在C#中實現相同,它可以正常工作。

public abstract class TestClass
{
    private readonly int data;

    protected TestClass(int data) { this.data = data; }

    public sealed class InnerClass : TestClass
    {
        private InnerClass(int data) : base(data) { }

        public static readonly TestClass CONSTANT = new InnerClass(5);
    }
}

為什么Java不允許這樣?

要創建內部 (而不是嵌套的靜態類),您需要一個封閉類的實例 - 在這種情況下您沒有。 請注意,C#中沒有內部類的直接等價 - C#中的嵌套類更像是Java中的嵌套靜態類,C#中類聲明中static的含義與類聲明中static的含義完全不同在Java中。

選項1

如果你真的希望它是一個內部類,你可以寫:

public static final TestClass CONSTANT = new SomeConcreteTestClass().new InnerClass(5);

(其中SomeConcreteTestClass是擴展TestClass的具體類)

或者,可怕的:

public static final TestClass CONSTANT = ((TestClass) null).new InnerClass(5);

請注意,您需要將聲明移出InnerClass ,因為內部類不能聲明除編譯時常量表達式之外的靜態變量:

如果內部類聲明顯式或隱式靜態的成員,則該編譯時錯誤,除非該成員是常量變量(第4.12.4節)。

所以你最終得到:

public abstract class TestClass
{
    private final int data;

    protected TestClass(int data) { this.data = data; }

    public final class InnerClass extends TestClass
    {
        private InnerClass(int data) { super(data); }        
    }
    public static final TestClass CONSTANT = ((TestClass) null).new InnerClass(5);
}

選項2

只需使InnerClass靜態:

public static final class InnerClass extends TestClass

static的添加是唯一需要改變的。 現在更像是一個C#嵌套類(雖然泛型的行為與往常不同......)理想情況下,你要重命名類,因為它不是內部類......

Java語言不允許內部類聲明顯式或隱式靜態的成員,除非該成員是常量變量,請參閱JLS 8.1.3

暫無
暫無

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

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