A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Saner 中级黑马   /  2014-3-29 11:11  /  1072 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Test1
{  
  public static int k = 0;   
  public static Test1 t1 = new Test1("t1");   
  public static Test1 t2 = new Test1("t2");   
  public static int i = print("i");   
  public static int n = 99;        
  public int j = print("j");        
  {      
   print("构造块");   
  }         
  static
  {      
   print("静态块");   
  }   
  public Test1(String str)
  {        
   System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);      
   ++i;        
   ++n;   
  }     
  private static int print(String str)
  {        
   System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);      
   ++n;        
   return ++i;   
  }     
  public static void main(String[] args)
   {      
   Test1 t = new Test1("init");   
   }
}
请大神对这段程序详解

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

8 个回复

倒序浏览
刚加注释,太纠结了,容易乱掉。给你几个原则吧。
你按原则来看,实在搞不懂,给我留言吧。
在代码上写注释,重复调用太多,太乱了。

原则:
1、JAVA程序,第一件事,找main函数。
2、新建对象。首先检查加载类,如果类字节码没有加载,先加载类的字节码(只加载一次)
3、先加载类的字节码后,类中static变量的引用空间就会被分配,并默认初始化。
4、static在默认初始化后,开始执行自定义初始化。(不管是静态块,还是静态变量。自上而下,依次执行)
5、在static中,如果新建对象,可以正常新建。
6、新建对象的顺序也是:
1)分配空间,默认初始化。
2)调用自定义初始化(先自上而下,执行初始化块和成员初始化,最后才执行构造函数)

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报 1 0
本帖最后由 阳春烟景 于 2014-3-29 11:57 编辑



public class Test1 {

          public static int k = 0;   //定义一个静态成员变量k,并初如化
          public static Test1 t1 = new Test1("t1");  //定义一个静态方法t1
          public static Test1 t2 = new Test1("t2");  //定义一个静态方法t2
          public static int i = print("i");   //这句话只是打印1,2,3,4...
          public static int n = 99;   // 定义一个静态成员变量n,并初如化
          public int j = print("j");//这里调用了下面的print函数,传进去的是j,打印结果是:1:j   i=0   n=0
          {
                  print("构造块"); //这里调用了下面的print函数,感觉这对{}没什么用。打印结果是:2:构造块   i=1   n=1
          }   
          static //这是静态方法,由于上面new了一个t1,所以打印结果是:3:t1   i=2    n=2
          {
                  print("静态块");  //这里调用了下面的print函数所以打印结果是:4:j   i=3   n=3
          }
//          由于每次调用Test1,print方法,都让i,n自增。所以接下来打印结果是:
//          5:构造块   i=4   n=4
//          6:t2   i=5    n=5
//          7:i   i=6   n=6
//          8:静态块   i=7   n=99
//          9:j   i=8   n=100
//          10:构造块   i=9   n=101
//          11:init   i=10    n=102
            
          public Test1(String str){ //这里是Test1方法
                 System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);      
                 ++i;        
                 ++n;   
          }  
          
          private static int print(String str){   //这是print函数   
             System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);      
             ++n;        
             return ++i;   
          }
          
          public static void main(String[] args){  //这是主函数
              Test1 t = new Test1("init");   
          }

}

点评

感觉,这段代码,难点不仅仅在注释。 更重要的难点在搞清楚执行顺序额。 这东西,写在代码里面,已经很不容易个。  发表于 2014-3-29 12:06

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报 2 0
阳春烟景 发表于 2014-3-29 11:54
public class Test1 {

          public static int k = 0;   //定义一个静态成员变量k,并初如化

我慢慢研究一下,很感谢
回复 使用道具 举报
水蓝 发表于 2014-3-29 11:44
刚加注释,太纠结了,容易乱掉。给你几个原则吧。
你按原则来看,实在搞不懂,给我留言吧。
在代码上写注释 ...

我新手 先研究一下
回复 使用道具 举报
本帖最后由 梦幻 于 2014-3-29 14:02 编辑

/*
Test1 t = new Test1("init");运行步骤:
1.静态成员在构造块之前运行进入内存,
2.构造块初始化。
3.构造函数初始化。

细分析:主函数现在创建了一个本类对象t,对象t中的静态成员都进入内存,开始从上往下执行,先执行k=0,
然后执行Test1 t1 = new Test1("t1");创建t1时,因为静态成员在创建t时已经存在,所以不需要再次引入静态成员,
但是创建t1时下面的静态还没有运行,所以此时i=0,n=0,

一、运行对象t1中过程:从上向下,
1、运行j = print("j"); -----------结果: 1:j   i=0   n=0
2、运行函数构造块{print("构造块");}-----结果:2:构造块  i=1  n=1
3、运行构造函数Test1(String str)-------结果:3:t1  i=2  n=2

二、运行对象t2,过程如下:
1、运行j = print("j"); -----------结果:4:j  i=3  n=3
2、运行函数构造块{print("构造块");}----结果:5:构造块  i=4  n=4
3、运行构造函数Test1(String str)------结果:6:t2  i=5  n=5

三、继续运行对象t:
1、依次完成对静态成员i和n的赋值运行-----结果7:i  i=6  n=6
2、完成静态函数构造块的初始化:static {  print("静态块"); }---结果:8:静态块  i=7  n=99
3、完成变量j的赋值,运行print("j");---结果:9:j  i=8  n=100
4、运行构造块{print("构造块");}-----结果:10:构造块  i=9  n=101
5、运行构造函数 Test1(String str) ----结果:11:init  i=10  n=102
*/



public class Test1
{  
   public static int k = 0;   //在类中定义了一个静态的整形变量k
   
   /*创建了两个个静态的本类对象t1,t2,
   并且这两个对象通过构造函数Test1(String str)进行了初始化
   在建立两个对象之前类中所有的静态成员都已经存在,只是下面的静态成员还没有运行
   此时相应的值 i=0,n=0*/

   public static Test1 t1 = new Test1("t1");
   public static Test1 t2 = new Test1("t2");   
  
   public static int i = print("i");   
   public static int n = 99;
   
   public int j = print("j"); //每个对象中都有一个自己的变量j,每个对象都需要运行赋值一次
  
   
   {      
   print("构造块");   //构造函数块,在构造函数之前
   }         
  
   
   static
   {      
   print("静态块");   //静态构造块,主函数建立对象t时已经存在,之后再建立对象,不在运行初始化
   }   

  public Test1(String str)
  {        
    System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);      
    ++i;        
    ++n;   
   }        //构造函数,每建立一个对象都要初始化一次

   private static int print(String str)
  {        
    System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);      
   ++n;        
    return ++i;   
   }       //print函数,i和j 赋值时调用


   public static void main(String[] args) //主函数,程序都是从主函数开始运行
   {      
   Test1 t = new Test1("init");   
    }
}

评分

参与人数 1技术分 +2 收起 理由
朱神必 + 2

查看全部评分

回复 使用道具 举报
class Test1
{  
  // 类加载器,先运行静态变量和静态代码块,并且只执行一次
  // 除main方法所在的类和第一次生成对象,会执行静态变量和静态代码.
//  第二次生象时,只会初始非静态变量 和 非静态代码块。再执行构造方法体。
  public static int k = 0;
  //静态变量
  //1:j   i=0   n=0
  //2:构造块   i=1   n=1
  //3:t1   i=2    n=2
  public static Test1 t1 = new Test1("t1");   
  //静态变量
  //4:j   i=3   n=3
  //5:构造块   i=4   n=4
  //6:t2   i=5    n=5
  public static Test1 t2 = new Test1("t2");   
  //7:i   i=6   n=6
  public static int i = print("i");   
  public static int n = 99;
  public int j = print("j");  
  {      
   print("构造块");  
  }  

  static
  {
         print("静态块");  
         System.out.println("初始化完成");
  }
  
  public Test1(String str)
  {        
   System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);   
   System.out.println();
   ++i;        
   ++n;   
  }  
  
  
  private static int print(String str)
  {        
   System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);      
   ++n;        
   return ++i;   
  }   
  public static void main(String[] args)
   {   
    //9:j   i=8   n=100
    //10:构造块   i=9   n=101
    //11:init   i=10    n=102
  
      Test1 t = new Test1("init");
      System.out.println( );   
   
      Test1 t2 = new Test1("init");   
   }
}

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
比较复杂的代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马