2

JLS 15.9.2告诉我们如何确定一个封闭实例:让 C 为要实例化的类,让 i 为正在创建的实例。

如果 C 是内部类,则 i 可能有一个立即封闭的实例(第 8.1.3 节),确定如下:

[...]

如果 C 是本地类,则:

  • 如果 C 出现在静态上下文中,则 i 没有立即封闭的实例。

  • 否则,如果类实例创建表达式出现在 静态上下文中,则会发生编译时错误。

  • 否则,令 O 为 C 的直接封闭类。令 n 为整数,使得 O 是出现类实例创建表达式的类的第 n 个词法封闭类型声明。

i 的直接封闭实例是 this 的第 n 个词法封闭实例。

我没明白粗体字是什么意思。让我提供我不应该编译的示例:

class A{
    int a;
    public static void main (String[] args) throws java.lang.Exception{
        class Foo{
            void bar(){
            }
        }
        Foo f = new Foo(); //Instance creation expression occured in the static context
    }
}

演示

那有什么问题?你不能提供一个描述第二点的实际例子吗?

4

2 回答 2

0

我想以下情况的意思是:

public class A {

   public class B { /* ... */ }

   public static void createB() {
      new B();  // <<=== This should fail
   }
}

标记的行应该失败,因为内部类 B 不是静态的,所以它需要封闭 A 的实例。没有这样的封闭实例,因为方法createB()是静态的。

更新:我误解了关于内部类的问题,这就是我的示例所显示的。在本地类的上下文中,我也无法解释文档。

于 2015-01-07T08:12:12.560 回答
0

您应该阅读这两行:

  • 如果 C 出现在静态上下文中,则 i 没有立即封闭的实例。

  • 否则,如果类实例创建表达式出现在静态上下文中,则会发生编译时错误。

您的情况是第一种情况-您Foo在静态上下文(main方法)中定义了类,因此该实例f没有封闭实例。

但是,如果您Foo在方法之外定义类main,并尝试在方法中创建 的实例Foomain则会出现错误,除非您更改Foo为静态类。

class A
{
    int a;
    class Foo
    {
        void bar()
        {
        }
    }
    public static void main (String[] args) throws java.lang.Exception
    {
        Foo f = new Foo(); // this should fail
    }
}
于 2015-01-07T08:12:41.533 回答