Java字段初始化顺序

时间:2014-12-20 17:41:55

标签: java static

class revi {

    static {
        i = 3;
        System.out.println("Hello World!");
    }
    static int i = 15;

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

以上程序不会在i=3给出任何错误;但是当我们在i静态块方法中调用println()时,它会显示错误

revi.java:6:错误:非法转发引用         System.out.println(“Hello World!”+ i);                                           ^ 1错误

class revi {

    static {
        i = 3;
        System.out.println("Hello World!" + i);
    }
    static int i = 15;

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

但如果像这样修改上面的程序它工作(静态变量首次加载)println方法没有错误

class revi {

    static int i = 15;

    static {
        i = 3;
        System.out.println("Hello World!" + i);
    }

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

请解释内部流程......

3 个答案:

答案 0 :(得分:7)

部分8.3.3 of the JLS

中介绍了这一点
  

使用类变量,其声明在使用后以文本形式出现有时受到限制,即使这些类变量在范围内(第6.3节)。具体来说,如果满足以下所有条件,则为编译时错误:

     
      
  • 在使用类变量后,类或接口C中的类变量声明以文本形式出现;

  •   
  • 在C的类变量初始值设定项或C的静态初始值设定项中,use是一个简单的名称;

  •   
  • 使用不在作业的左侧;

  •   
  • C是封闭使用的最里面的类或接口。

  •   

在您的情况下,当您打印值时,所有为真,因此错误。

更改代码以移动声明后,第一个项目符号不再成立,因此编译。

答案 1 :(得分:1)

在case1中,您正在使用i初始化变量3,并使用15初始化第2行。最终结果是变量i保持15

在案例2中,您将获得Illegal forward reference error,因为您在定义之前尝试使用变量i已更新根据JLS,尚未定义的静态变量只能在分配中使用,除非它们以类名称为前缀(在这种情况下,它们会获得默认值)。例如,

static {
    i = 3;
    i = i * 2; // will give you compile error
    System.out.println("Hello World!" );
}

E.g.2在这种情况下,您将访问前缀为类名的变量i。但请记住,revi.i的值为0而不是15,因此输出将为0

static {
    i = revi.i * 2; // this line is similar to  revi.i = revi.i * 2;
    System.out.println("Hello World!" + revi.i );
}
static int i = 15;


在案例3中,您首先声明并初始化i=5,然后为其分配3。因此,初始化后i将保持3作为其值

答案 2 :(得分:0)

当执行java类时,JVM按顺序执行几个步骤的步骤很少。

从上到下识别静态成员。 从上到下执行静态变量赋值和静态块。 执行主要方法。 在这些阶段中,有一个名为RIWO(只读间接写入)的状态用于静态变量。

在RIWO期间,无法使用其引用直接访问变量。相反,我们需要使用间接方式来调用某些变量。

RIWO State

您可以参考该链接获取详细信息。