正确代码如下:public class StaticClass{
    static{
        a = 1;
        System.out.println("-----------------");
    }
    public static int a = 10;}错误代码如下:public class StaticClass{
    static{
        a = 1;
        System.out.println("-----------------"+a);
    }
    public static int a = 10;}问什么静态块里可以赋值不可以引用?

解决方案 »

  1.   

    public static int a = 10;
    放到静态代码块前面。先定义,再使用。
      

  2.   

    本质上是可以的,只不过javac这个编译器做出了限制假设编译可以通过,类初始化做了什么?先为a分配内存,赋默认值0然后将a赋值为1再将a赋值为10javac或许是因为觉得这个赋值顺序会导致混乱,干脆禁止通过编译
      

  3.   

    根据JVM的spec的一部分定义“The static initializers and class variable initializers are executed in textual order. They may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope. This restriction is designed to catch, at compile time, most circular or otherwise malformed initializations.”可以看出类变量的初始化顺序是按照它们出现在代码中的顺序来的,而且是不可以在它们定义之前来引用。 这个限制是为了在编译器抓住那些怪异的初始化过程。就是这个例子提到的。那为什么可以赋值,却不能在输出中出现呢? 赋值是putstatic操作,引用是getstatic操作,我个人理解是编译器只会认为getstatic操作是一个引用,所以就编译错。而且如果去掉编译器的这个限制的话,我认为这种写法也是可以执行的。你可以把a=1的赋值语句替换成a++就可以看到a++这一句是编译错的,因为a=1是一个简单的putstatic操作,但是a++则包含了一个getstatic的操作。
      

  4.   

     “赋值是putstatic操作,引用是getstatic操作”是什么操作,有什么特性?
      

  5.   

    是jvm字节码指令,一个是为静态变量赋值-压栈,一个是获取静态变量值-出栈
      

  6.   

    ls正解,当你访问一个static的变量的时候,在class文件中其实就是一个getstatic的操作。依次类推putstatic。