public class Test
{
    public static void main(String[] args)
    {
        Super t = new Super();
     }
}
class Super
{
    static
    {   
        System.out.println("静态加载执行输出");
        int i;
        System.out.println(i);  //为什么这里没有I没有被初始化  我想问下这里JVM是怎样对内存操作的?把I压到内存的什么地方了 或者是可以做个标记不给I分配空间吗?类加在是放生在执行了JAVA 命令之后的吗???         }
}

解决方案 »

  1.   

    在静态块中只能调用静态变量或静态方法,如果直接在static块中定义变量,那么就是局部变量,局部变量在使用前必须被初始化!
    以你的例子而言:
                 JVM虚拟机诞生->JVM加载Test类(Test的Class对象存储在堆区,Test字节码存储在方法区)->main方法压栈->加载Super类->初始化成员变量(int=0,boolean=false等,如果存在父类,先初始化父类)->执行静态块(你的i必须分配空间才能被使用)->调用Super构造方法(实例化Super对象)->main方法出栈->JVM虚拟机死亡
      

  2.   

    类加载的顺序是静态块,非静态块和属性平级(即看写的位置),最后构造
    class Super 

        static 
        {  
            System.out.println("静态加载执行输出"); 
            int i ; 
    //        System.out.println(i);      } 
        { System.out.println("asdfasdffffffffffffffff");}
        int i  = test();
        public Super() {
    System.out.println("gouzhao");
    }
        public int test(){
         System.out.println("test");
         return 9;
        }
        

      

  3.   

    这里可以通过查看Think in java,得到比较完整的答案。
    java需要保证任何变量在使用之前得到正确的初始化,java按照它自己的方式达到了这样的要求,在函数中通过编译检查排除这样的错误。例如
      void f() {
         int i;
         i++;
    }
    这样书写的代码在编译时就会报出i没有被初始化的错误;当然编译器是能够给i一个默认值的,但这很可能是一个程序书写的bug,如果给出了默认值,那等于就掩盖了这个错误。
      如果是java类的primitive data 属性成员,情况就有点不同。因为任何方法都可以初始化或者使用这些数据,所以强迫去初始化它是不实际的。如果随便给它赋予一个废值也是不安全的,所以类的primitive data属性成员保证会获取一个初始值,比如int 类型的就是0,boolean类型的为false,char 是null。
      Super t = new Super(); 执行时,引起类Super的加载和初始化,当执行静态块时
        static 
        {  
            System.out.println("静态加载执行输出"); 
            int i; 
            System.out.println(i);  
        } 在编译会报出错误,i没有初始化。这里相当于上面的f().