2015-03-19 76 views
4

我不明白爲什麼在Java中,下面的代碼錯誤:爲什麼嵌套類在Java和C#之間表現不同?

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);一部分。 的錯誤是:

I:\Documents\NetBeansProjects\TestingGround\src\testingground\TestClass.java:22: error: non-static variable this cannot be referenced from a static context public static final TestClass CONSTANT = new InnerClass(5); ^I:\Documents\NetBeansProjects\TestingGround\src\testingground\TestClass.java:22: error: Illegal static declaration in inner class TestClass.InnerClass public static final TestClass CONSTANT = new InnerClass(5); ^ modifier 'static' is only allowed in constant variable declarations 2 errors

如果我試圖實現在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不允許這樣做?

+0

我更新了標題......不幸的是,這個問題很多類似的重複http: //www.bing.com/search?q=Why+nested+classes+behave+differently+between+Java+and+C%23% ...但Jon Skeet回答的並不多 - 因此讓我們有另一個:)隨意更名標題以更好地反映您的問題。 – 2015-03-19 07:02:01

+0

@AlexeiLevenkov這兩個'重複'都沒有解決這個問題。一個是問爲什麼一個C#嵌套類沒有像Java內部類那樣訪問其外部類的內部。有人問,Java靜態類和C#靜態類之間有什麼區別,但是從這個問題給出的問題答案來看,這有點認知上的飛躍。 – Pharap 2015-03-19 07:17:45

回答

7

要創建一個inner class(而不是嵌套靜態類),您需要一個封閉類的實例 - 在這種情況下您沒有一個。請注意,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,作爲內部類不能聲明靜態變量以外的編譯時間常數表達式:

It is a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable (§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#嵌套類(雖然泛型的行爲與往常一樣)。理想情況下,您將重命名該類,因爲它不是內部類...

+0

當我被允許時,我會在4分鐘內接受此信息。我不知道有可能在Java中實例化靜態類,因爲我更習慣於C#。 (無論如何,這些並不是我的類的實際名稱,爲了演示的目的,我簡化了我的類。)我知道泛型將有不同的應用,Java使用類型擦除而不是C#的技術,但無論如何感謝您的領導。由於各種原因,大多數語言傾向於對泛型進行不同的處理。 – Pharap 2015-03-19 06:53:44

1

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

+0

這基本上是第二個錯誤的重新說明,因此沒有幫助。 – Pharap 2015-03-19 06:58:20

+0

@Pharap:這是對第二個錯誤的* source *的解釋,並引用了JLS。這不是一個完整的解釋,但我不會說這是「沒有幫助」。 – 2015-03-19 07:18:00

+0

@JonSkeet除了這個事實沒有什麼幫助之外,不管複雜多麼簡單或複雜的問題,僅僅複製並粘貼JLS的一部分而不做進一步的闡述並不能提供很好的答案。 – Pharap 2015-03-19 07:27:30

相關問題