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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄连兵 中级黑马   /  2012-6-19 10:23  /  2993 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黄连兵 于 2012-6-19 11:22 编辑

看完视频,对这两个概念理解还是不太清晰,请同学们一起讨论下。
静态代码块优于对象而存在,是类的共性,被此类的所有对象共享,在加载时只会执行一次。
构造代码块的执行介于static与构造函数之间,也是此类对象所共有的吗?有资料显示构造代码块是供此类的所有构造函数所共享,是不是任何一个构造函数被new调用,都会执行?

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

14 个回复

倒序浏览
本帖最后由 黑马张扬 于 2012-6-19 10:33 编辑

静态代码块是给类进行初始化的 只在加载时执行一次
构造代码块是给对象进行初始化的 是对象一建立就执行  优先于构造函数执行  构造代码块定义的是不同对象的共性初始化内容
而构造函数则是给对应的对象进行初始化的
回复 使用道具 举报
是滴,简单一句话:静态代码块为类初始化,构造代码块为所有对象初始化,构造函数为对应参数的对象初始化。所以嘛,静态代码块只执行一次,也就是在加载类的时候执行;构造代码块是每创建一个对象就执行一次;构造函数是只有创建对应参数的对象时才被调用执行。
回复 使用道具 举报
构造代码块是给所有对象初始化,对象一建立就运行有限构造函数执行
回复 使用道具 举报
是的,构造代码块一看这个名字就知道和构造函数有关,构造函数是在new对象的时候调用的,所以构造代码块也是在这个时期被调用,只不过早于构造函数,你可以写几行代码debug一下看看执行顺序。那样更容易理解。

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
给个简单代码,一看就知道了
public class neibulei {
       
       
        neibulei() {
                System.out.println("i am contructor");
        }
       
        neibulei(int i ) {
                System.out.println("i am con i");
        }
       
        {
                System.out.println("i am {}");
        }
       
        public static void main(String[] args) {
                new neibulei();
                new neibulei();
                new neibulei(1);
        }
       
        static{
               
                System.out.println("i am static");
        }
}

运行结果是:
i am static
i am {}
i am contructor
i am {}
i am contructor
i am {}
i am con i

可以看出:调用顺序是 静态代码块 -->  构造代码块  -->  构造函数

问题1:构造代码块的执行介于static与构造函数之间,也是此类对象所共有的吗?
构造代码块区别于静态代码块,静态代码块是类所共有的,也就是属于类不属于对象,不论你new多少对象,静态代码块只在类加载的时候运行一次。
而构造代码块明显不是共有的,而是隶属于对象的,每一次new对象的时候运行一次。

问题2:是不是任何一个构造函数被new调用,都会执行?
是的,都会。直接看我给的例子就知道啦,无论你调用哪一种构造函数,都会运行构造代码块里的内容

点评

学习啦!!  发表于 2012-6-19 14:53

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 航天员??呵呵

查看全部评分

回复 使用道具 举报
多谢楼上各位~!差不多清楚了!
回复 使用道具 举报
多谢楼上各位~!差不多清楚了!
回复 使用道具 举报
耿鑫 中级黑马 2012-6-19 15:48:53
9#
楼主扩展一下,存在继承的情况下这几个执行顺序是什么? 答案还是一样 参见代码如下:
package org.gengxin;

public class Test
{
        public static void main(String[] args)
        {
                new S();
                new S();
        }
}

class P
{
        static
        {
                System.out.println("P static block");       
        }
       
        {
                System.out.println("P construct block");
        }
        public P()
        {
                System.out.println("P constructor");
        }       
}

class Q extends P
{
        static
        {
                System.out.println("Q static block");
        }
       
        {
                System.out.println("Q construct block");
        }
        public Q()
        {
                System.out.println("Q constructor");
        }
}

class S extends Q
{
        static
        {
                System.out.println("S static block");
        }
       
        {
                System.out.println("S construct block");
        }
       
        public S()
        {
                System.out.println("S constructor");
        }
}

运行结果:
P static block
Q static block
S static block
P construct block
P constructor
Q construct block
Q constructor
S construct block
S constructor
P construct block
P constructor
Q construct block
Q constructor
S construct block
S constructor

总结:类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,座椅静态代码快也就会执行一次;而构造方法和构造代码块则不然,每此生成一个对象的时候都会调用构造代码块和构造函数,所以new一次就会调用构造代码块和构造函数一次。
如果继承体系中既有静态代码块又有构造方法和构造代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的构造静态大妈块,然后再去执行最顶层的构造代码块和构造函数,一直执行到最底层类的构造代码块和构造函数,注意:静态代码块只执行一次。
回复 使用道具 举报
当此类对象一建立,构造代码快就会优先于构造函数执行。
回复 使用道具 举报
构造代码块:给对象初始化,对象一建立就运行,而且优先于构造函数执行
构造代码块是给所有对象进行统一初始化,构造函数是给对应的对象初始化。
构造代码块定义的是不同对象的共性的初始化内容。

静态代码块:随着类的加载而加载,只执行一次,优先于主函数,用于给类初始化。
回复 使用道具 举报
//静态代码块,构造函数,构造代码块的执行顺序:e  a b d f  j b d  hallo World!
class ToSequenced
{
      static
      {
           System.out.println("a");//静态代码块优先于其他,且只有被主函数调用的类的静态才会执行,只执行一次 2         
      }

      {
           System.out.println("b");//先调用ToSequenced(intx),所以ToSequenced中的构造代码块先执行  3

                                         //再次调用构造函数ToSequenced(intx)所以构造代码块再优先执行一次 7     

      }      
     ToSequenced()//没被调用,不执行
      {
          System.out.println("c");
      }

     ToSequenced(int x)
      {
               System.out.println("d");//被调用,执行  4

                                                   //new ToSequenced(6)调用再执行一次 8

      }

}

class ToSequenced2
{
      static
      {
            System.out.println("e");//主函数所在类的静态最先执行  1
      }

      {
             System.out.println("f");//ToSequenced2(int x)被调用  ,构造代码块先于ToSequenced2(intx)执行  5
      }
      public static void main(String[] args)
      {
                     new ToSequenced(4);//有变量所以执行的是ToSequenced(int x)
                     new ToSequenced2(5);
                     new ToSequenced(6);
                     System.out.println("Hello World!");//最后执行  9

     }                 

    ToSequenced2()
   {
         System.out.println("i");
   }

   ToSequenced2(int x)
   {
           System.out.println("j");//被调用执行  6

   }
}

回复 使用道具 举报
当成员被静态修饰符修饰后就不存在于堆内存中了,存在于方法区,被对象共享,还可以被类名调用,类加载的时候就加载,先于对象存在。构造代码块是给所有对象进行统一初始化,对象一建立就运行,而且优先于构造函数执行,对象调用构造函数的时候就会运行,但是先于构造函数执行。
回复 使用道具 举报
是,每一次new一个新对象都会执行,我试验了一下

public class jjj{
         
         {
                 System.out.println(5);         
                 System.out.println(add());
                 }
         
         public jjj() {
                System.out.println(3);
        }
         
         static int add(){
                 return 2+333;
         }
         public static void main(String[] args){
               
                 new jjj();//打印出现的顺序就能证明
         }
}
回复 使用道具 举报
杨朔 发表于 2012-6-20 00:20
是,每一次new一个新对象都会执行,我试验了一下

public class jjj{

你这个是调用了静态的方法。所以不行啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马