为什么嵌套类在Java和C#之间表现不同?

时间:2015-03-19 06:41:55

标签: java 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);部分。 错误是:

  

I:\文件\的NetBeansProjects \ TestingGround \ SRC \ testingground \ TestClass.java:22:   错误:非静态变量,不能从静态引用   context public static final TestClass CONSTANT = new InnerClass(5);                                              ^ I:\ Documents \ NetBeansProjects \ TestingGround \ src \ testingground \ TestClass.java:22:   错误:内部类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不允许这样做?

2 个答案:

答案 0 :(得分:7)

要创建inner class(而不是嵌套的静态类),您需要一个封闭类的实例 - 在这种情况下您没有。请注意,C#中没有内部类的直接等价 - C#中的嵌套类更像是Java中的嵌套静态类,而C#中类声明中static的含义与{的含义完全不同{1}}在Java中的类声明中。

选项1

如果你真的希望它是一个内部类,你可以写:

static

(其中public static final TestClass CONSTANT = new SomeConcreteTestClass().new InnerClass(5); 是扩展SomeConcreteTestClass

的具体类

或者,可怕的:

TestClass

请注意,您需要将声明移出public static final TestClass CONSTANT = ((TestClass) null).new InnerClass(5); ,因为内部类不能声明除编译时常量表达式之外的静态变量:

  

如果内部类声明一个显式或隐式静态的成员,那么这是一个编译时错误,除非该成员是一个常量变量(§4.12.4)。

所以你最终得到了:

InnerClass

选项2

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); } 静态:

InnerClass

添加public static final class InnerClass extends TestClass 是唯一需要的更改。现在更像是一个C#嵌套类(虽然泛型的行为与往常不同......)理想情况下,你要重命名该类,因为它不是内部类......

答案 1 :(得分:1)

Java语言不允许内部类声明显式或隐式静态的成员,除非该成员是常量变量,请参阅JLS 8.1.3