java报错非法的前向引用?

class BB
{
    static int a = 0 ;
    public BB()
    {
        a++ ;
        System.out.println("执行BB" + a) ;
    }

    public void printA()
    {
        System.out.println("a= " + a) ;
    }
}

public class CC
{
    static
    {
        a = new BB() ;
        a.printA() ;
    }
    static BB a = new BB() ;

    public staic void main(String args[])
    {
        CC c = new CC() ;
    }
}

我在静态代码块中已经初始化过了, 为什么还是会报错说非法的前向引用, 这是为什么呢?

阅读 7.3k
2 个回答

参考 Restrictions on the use of Fields during Initialization

只有在全部满足以下4点的情况下,成员变量的声明才必须在使用之前,否则顺序无关

  • 使用出现在C的实例/静态变量初始化,或者C的实例/静态初始化块中 (题中a.printA()出现在静态初始化块中,满足)
  • 使用不在赋值表达式左边 (题中a.printA()非赋值表达式,也即不在赋值表达式左边,满足)
  • 使用是通过简单名称 (题中a.printA()不带类名,满足)
  • C是包含该使用的直接类/接口 (C即为题中CC,满足)

简单来说, 在

static BB a = new BB();

声明之前的static initialization block中使用,只能出现在复制表达式左边,除非带上类名(fully qualified)

改法1:

static BB a = new BB() ;
static
{
    a = new BB() ;
    a.printA() ;
}

改法2:

static
{
    a = new BB() ;
    CC.a.printA() ;
}
static BB a = new BB() ;
public class CC
{
    static BB a = new BB() ; //静态变量和静态区的初始化顺序和声明顺序一致
    static
    {
        a = new BB() ;
        a.printA() ;
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏