代码1:
Java代码 复制代码   1. public class MyObject {  
   2.       
   3.     public void getX(){  
   4.         System.out.print("x =" + x);  
   5.     }  
   6.       
   7.     static int x = 10;  
   8.       
   9.     static {  
  10.         x = 20;  
  11.     }  
  12.           
  13.     public static void main(String [] args){  
  14.         MyObject myObject = new MyObject();  
  15.         myObject.getX();  
  16.     }  
  17.       
  18. }  public class MyObject {

public void getX(){
System.out.print("x =" + x);
}

static int x = 10;

static {
x = 20;
}

public static void main(String [] args){
MyObject myObject = new MyObject();
myObject.getX();
}

}此时打印结果是:
x = 20
貌似static块是按照顺序从上往下执行的。但是代码2
Java代码 复制代码   1. public class MyObject {  
   2.       
   3.     public void getX(){  
   4.         System.out.print("x =" + x);  
   5.     }  
   6.           
   7.     static {  
   8.         x = 20;  
   9.     }  
  10.       
  11.     static int x = 10;  
  12.       
  13.     public static void main(String [] args){  
  14.         MyObject myObject = new MyObject();  
  15.         myObject.getX();  
  16.     }  
  17.       
  18. }  public class MyObject {

public void getX(){
System.out.print("x =" + x);
}

static {
x = 20;
}

static int x = 10;

public static void main(String [] args){
MyObject myObject = new MyObject();
myObject.getX();
}

}
编译通过,此时打印结果是:
x = 10
难道是说 x 先被初始化为0?接着代码3:
Java代码 复制代码   1. public class MyObject {  
   2.       
   3.     public void getX(){  
   4.         System.out.print("x =" + x);  
   5.     }  
   6.           
   7.     static {  
   8.         System.out.println(x);  
   9.     }  
  10.       
  11.     static int x = 10;  
  12.       
  13.     public static void main(String [] args){  
  14.         MyObject myObject = new MyObject();  
  15.         myObject.getX();  
  16.     }  
  17.       
  18. }  public class MyObject {

public void getX(){
System.out.print("x =" + x);
}

static {
System.out.println(x);
}

static int x = 10;

public static void main(String [] args){
MyObject myObject = new MyObject();
myObject.getX();
}

}
如果是初始化为0.
那么为何此时编译不过。
出错位置:System.out.println(x);

解决方案 »

  1.   

    static { 
    System.out.println(x); 

    哪里有初始化呢.
      

  2.   

    学习一下,我也不太明白!好像是static代码块会最先初始化,
      

  3.   

    jvm的加载顺序:
    父类static块,父类构造函数;
    子类static块,子类构造函数
      

  4.   

    楼上的有点问题
    jvm的加载顺序: 
    父类static块,子类static块,父类构造函数,子类构造函数; 
      

  5.   

    不好意思,如果你是真心来解决问题的,那我真的很谢谢你。
    但如你目前的回答,真的是让我很无助。来这里提问题,是想得大家及时得到帮助,或一起讨论,交换看法,及时的获得对自己有用的信息。这才应该是csdn的风气不是吗?但是,请看你的回答。
    看jls --- 我很难从中得到什么有用的信息。至少不是很直观的。请问如果这也算是回答问题的话,那么每个帖子都回复成---去看世界上所有的java书籍吧!肯定能够找到答案!你意下如何?我看至少比你的语气还亲切点,呵。最后,如果你知道答案,我很乐意向你请教:)。
      

  6.   

    1、都是静态的话,顺序从上而下
    2、x先被初始化为20,然后有用10覆盖了
    3、static {
    System.out.println(x);//执行这句的时候,x还没有被初始化,main也没开始执行,所以出错
    }static int x = 10;
      

  7.   

    类在jvm加载时就执行了,先于主线程和任何实力方法
      

  8.   


    LZ别生气了,大家都挺热情的啊
    1、都是静态的话,顺序从上而下.
    2.初始化为0.
    public class MyObject {public void getX(){
    System.out.print("x =" + x);
    }
    static int x;  //你没有定义哦,既然没定义,是不会初始为0的;类方法怎样我不清楚,但是static块确实是在main()方法
    //之前执行的.
    static {
    System.out.println(x);
    }
    //static int x = 10;
    public static void main(String [] args){
    MyObject myObject = new MyObject();
    myObject.getX();
    }}
      

  9.   

    先谢谢各位的帮助,另外java2000_net的话我也听进去了,很是感谢!
    说的没错,学不到只能怨自己。每个人都应摆正心态,不管你是高手还是小白。
    我还是有一个问题没有看懂,希望大家帮忙看一下。
    public class MyObject {public void getX(){
    System.out.print("x =" + x);
    }static {
    x = 20;
    }static int x = 10;public static void main(String [] args){
    MyObject myObject = new MyObject();
    myObject.getX();
    }}
    为什么以上这样写就不会编译出错呢?
    但是把第一段static块中的x = 20;换成System.out.print("x =" + x);就会编译不过去呢?
    之前都没经过声明定义啊?public class MyObject {public void getX(){
    System.out.print("x =" + x);
    }static {
    System.out.println(x);
    }static int x = 10;public static void main(String [] args){
    MyObject myObject = new MyObject();
    myObject.getX();
    }} 
      

  10.   


    我只是希望帮助提问的人自己找答案而已,而不是摊开手要答案,我并不在乎分数
    你要这么想我也没办法
    其实这个在JLS(第3版)里面有说到12章里面谈到,大意是
    静态字段是在加载类时初始化为默认值,不需要调用代码
    而显式初始化是作为初始化类的一部分执行的,并且必须按顺序调用静态初始化语句,并且"不能引用其声明出现在使用之后的类中声明的变量"(原话),也就是说,你只要不把它取出来就可以针对你的代码2分析:x=30;
    代码是:
    bipush 30
    putstatic
    没有涉及取值操作getstatic,所以允许执行改动一下为
    x++;
    代码变为:
    getstatic
    iconst_1
    iadd
    putstatic
    这时涉及了取值操作getstatic
    则抛出"非法向前引用"错误
    再改动一下,将
    static int x = 10;
     放入静态域,变为
    static {int x = 10;}
    这时的x是在局部定义的,不算类静态变量,存取方式也不同,所以会再抛出错误
    反编译之后也可以见到其的确不再是类静态变量了
    因此静态域跟静态字段也是不同的,不要想当然地以为static {int x = 10;}就等于static int x = 10;了综上所述,我想应该可以解释楼主的问题了
    不过我个人不善表达,可能描述得不太清楚
      

  11.   

    或者说这样子改动一下:

    static int x = 10; 
    改为
    static int x ;
    这时,可以确实看到
    x=30;
    这句的确曾经被执行过 
      

  12.   

    是类的静态成员,只要不碰到getstatic,大概都可以
    "这种限制用于在编译时检测大多数循环或其他不良的初始化"(JLS原话)
    所以可以判断这个限制是JAVA特地设置的一条规范"不能引用其声明出现在使用之后的类中声明的变量"个人愚见,不同意的就拍我砖吧
      

  13.   

    我就是在阅读sybex考试教材的时候看到的。所以才能了解一下。