在java中加载类时会发生什么?

时间:2014-05-22 17:53:29

标签: java

我对加载课程的过程感到困惑。执行类成员的顺序是什么?

请参阅以下内容:

class L {

    static void fr(){
        a=1;
        b=3;
        a=b;
    }

    static{
        a=3;
        b=1;
        a=b;// here the problem:cannot reference a field before it is defined
    }

    static int a;
    static int b;

    public static void main(String args[]) {

    }
}

每当我将ab的声明移到静态块之前的顶部时,编译工作正常。所以我需要了解这些东西如何解决上述问题。

2 个答案:

答案 0 :(得分:4)

在Java中,如果类变量不是初始化它的表达式,则在声明它之前引用它是非法的。 Java将以文本顺序在类中执行初始值设定项。

Section 12.4.2 of the JLS州:

  

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。

Section 8.3.3 of the JLS州:

  

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

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

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

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

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

  •   

所有这些都是真的。声明在a=b;中使用后出现。它在静态初始化器中。它不在作业的左侧,而且它是最里面的(唯一)类。

最简单的编译方法是将声明移到源代码中的静态初始化程序之上。

有趣的是,将a=b;替换为a=L.b;也会将其编译,因为对b的引用不再是“简单”。

答案 1 :(得分:0)

首先加载类并验证整体结构。然后验证方法并检查外部链接。然后执行静态init。这是执行静态块的时候。

但你的问题显然是编译器,而不是类加载。您需要将静态变量声明移到静态块之上。与课程加载完全无关。

提示:了解编译时错误和运行时异常之间的区别。你看到的是来自编译器的错误消息。 (你很幸运,你没有抓到血腥的地狱并关闭投票,因为你的问题中没有包含确切的错误信息。)