class Base{
    static{
         System.out.println("{父类加载}");
         }
     static int a=getValue("静态:获取父类a值");
     Base(){
          System.out.println("调用父类无参构造函数,现打印父类a赋值结果:"+a);
          a++;
          printA();
      }
     {
          System.out.println("{父类实例初始代码块}");    
      }
     Base(String s){
          System.out.println("父类带参构造函数"+s);    
      }
     void printA(){
         System.out.println("父类赋值结果a="+a);
     }
     static int getValue(String s){
          System.out.println("静态:父类原始a="+a);
          System.out.println(s);
          return ++a;
      }
 }
public class Child extends Base{
    static{
         System.out.println("{子类加载}");    
     }
     static Child child=new Child();
     static int a=getValue("静态:获取子类a值");
     
    Child(){
         System.out.println("调用子类无参构造函数,现打印子类a赋值结果:"+a);
         a++;
         printA();
     }
    {
          System.out.println("{子类实例初始代码块}");    
      }
     Child(String s){
          System.out.println("子类带参构造函数"+s);    
      }
    void printA(){
         System.out.println("子类赋值结果a="+a);
     }
    static int getValue(String s){
         System.out.println("静态:子类原始a="+a);
         System.out.println(s);
         return ++a;
     }
    public static void main(String[] args){
         //new Child("实例化子类");
         new Child();
     }
 }
打印结果如下:
---------------------------------------------------------
{父类加载}
静态:父类原始a=0
静态:获取父类a值
{子类加载}
{父类实例初始代码块}
调用父类无参构造函数,现打印父类a赋值结果:1
子类赋值结果a=0
{子类实例初始代码块}
调用子类无参构造函数,现打印子类a赋值结果:0
子类赋值结果a=1
静态:子类原始a=1
静态:获取子类a值
{父类实例初始代码块}
调用父类无参构造函数,现打印父类a赋值结果:2
子类赋值结果a=2
{子类实例初始代码块}
调用子类无参构造函数,现打印子类a赋值结果:2
子类赋值结果a=3
-------------------------------------------------------------------这是网上的一个例子,自己经测试输出正确如上,但是只看懂前面几个输出的结果,后面的就看不出了,在这想问下,为什么父类的构造方法中的 printA()没有被执行?还有,在代码的main方法里执行new Child()时,是不是产生了两个Child类型的对像,一个是没有被引用的匿名的,另一个是在实例化child类时里面不是有个child 类型的成员变量static Child child=new Child();吗?这个过程又产生一个被引用的Child类对象? 
还有,在main方法中实例子类时,当执行到static Child child=new Child();这一步时,是不是这一步的过程有点递归的味道?这一步的child变量实例化过程中完成后才会继续执行下一个静态变量static int a=getValue("静态:获取子类a值");?

解决方案 »

  1.   

    {父类加载}             //加载父类的静态代码块
    静态:父类原始a=0       //加载父类静态成员并调用getValue方法
    静态:获取父类a值        
    {子类加载}             //加载子类的静态代码块
    {父类实例初始代码块}    //加载子类静态new出新的对象时并首先调用父类的实例代码块
    调用父类无参构造函数,
    现打印父类a赋值结果:1  //之后便是父类的构造器
    子类赋值结果a=0        //构造器中调用子类A()方法
    {子类实例初始代码块}    //父类完了就调用子类实例初始化代码块
    调用子类无参构造函数,
    现打印子类a赋值结果:0   //然后是子类的构造器
    子类赋值结果a=1        //构造器中调用A子类()方法
    静态:子类原始a=1      //new child完成后接着再加载下一个静态语句并因此调用getValue()
    静态:获取子类a值        //在getValue中
    {父类实例初始代码块}    //静态代码块、成员、对象之类的加载完毕后进入main()函数执行new语句
    调用父类无参构造函数,
    现打印父类a赋值结果:2  //先调用父类实例初始化块
    子类赋值结果a=2        //父类构造器
    {子类实例初始代码块}   //子类初始化块
    调用子类无参构造函数,
    现打印子类a赋值结果:2   //
    子类赋值结果a=3        //子类构造器
      

  2.   

    哎,在平台上调试跟了好几次,还是没能理解,见难,/加载子类静态new出新的对象时并首先调用父类的实例代码块,我想说的是这个静态成员变量在NEW 的时候不是相当于实例化一个对象么,为什么这时实例这个对象时没有打印父类的静态变量而现在是首先调用父类的实例代码?还有,里面到底有几个a?为什么后面a的值重新初始化为0?还有,可不可以帮我解释一下类加载和类实例有什么不同,都分别执行或初始化哪些东西?
      

  3.   

    父类中的a是父类的,子类中a是覆盖了父类的,就像另一个a一样。类加载时是加载静态成员并在加载时初始化,类实例是在加载完后代码运行期间对实例成员初始化并分配内存,往往伴随着新对象的产生。类加载只有一次,静态初始化代码块只执行一次,而每次调用构造器时都会先调用实例初始化块。在new  Child时你是产生一个新对象,所以你调用的是构造器而不是静态初始化块,正像前面所说,静态初始化块只在加载时执行一次而且你只能从代码的顺序上改变jvm加载静态各种东西的顺序而不能自行调用它的初始化,所以你要记得,new新对象只是和构造器及实例初始化块有关(就目前浅显的知识而言)。
      

  4.   

    2楼是大神,我在debug中调试看了半天才算看明白
      

  5.   

    为什么在执行main方法前要去先加载父类而不是直接运行main方法呢?
      

  6.   

    对于这个为什么这样做呢,我不知道,就好比为什么main是程序的入口而不是其他
    方法一样,在加载类时执行静态初始化代码块是java规定的,为什么要这样,我想
    会有他的道理,只是我们不知道而已