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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© xiaobo 中级黑马   /  2014-1-27 10:41  /  1648 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

格式:
static
{
        静态代码块中的执行语句。
}

特点:随着类的加载而执行,只执行一次,并优先于主函数。
用于给类进行初始化的。
下面代码的执行顺序为什么是b c a c9 d?
  1. class  StaticCode
  2. {
  3.         int num = 9;
  4.         StaticCode()
  5.         {
  6.           System.out.println("b");
  7.         }
  8.         static
  9.         {
  10.            System.out.println("a");
  11.         }
  12.         {
  13.           System.out.println("c"+this.num);
  14.         }
  15.         StaticCode(int x)
  16.         {
  17.                 System.out.println("d");
  18.         }
  19.         public static void show()
  20.         {
  21.             System.out.println("show run");
  22.         }
  23. }
  24. class StaticCodeDemo
  25. {
  26.         static
  27.         {
  28.                 System.out.println("b");
  29.         }

  30.         public static void main(String[] args)
  31.         {
  32.                 new StaticCode(4);
  33.         }
  34.         static
  35.         {
  36.           System.out.println("c");
  37.         }
  38. }
复制代码



评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

10 个回复

倒序浏览
StaticCodeDemo类一加载就执行该类中的静态代码块,所以先输出了b、c再看主函数,new StaticCode(4);就把staticCode类加载进内存,所以就执行该类的静态代码块,所以就输出 了a,接着执行代码块的东西,代码块是给所有对象初始化的,所以优先于构造函数执行,所以就输出了c跟9,最后执行构造函数,给该对象进行初始化,输出了d。。依此输出的顺序是b c a c9 d

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
当加载StaticCodeDemo类时,两个静态代码块优先于mian方法,会先被执行,输出b和c,然后再进入mian创建匿名对象。而在对象被加载时,也是优先执行静态代码块,输出a。然后构造代码被执行,输出c9,最后构造方法,输出d,完成对象的初始化。执行结果是b c a c9 d

可以看一下我写的代码

  1. /*
  2. 1、静态代码块优先于mian方法执行
  3. 2、静态代码块优先于构造代码块执行
  4. 3、构造代码块优先于构造方法执行

  5. 静态代码块>构造代码块>构造方法

  6. 输出结果为:d b a c
  7. */

  8. package com.staticdemo;

  9.         public class StaticCodeDemo2
  10.         {
  11.                 static {
  12.                         System.out.println("d");                //第一
  13.                 }
  14.                 public static void main(String args[]){
  15.                         StaticDemo d1=new StaticDemo();
  16.                 }
  17.         }

  18.         class StaticDemo
  19.         {
  20.                 {
  21.                         System.out.println("a");                //第三
  22.                 }

  23.                 static{
  24.                         System.out.println("b");                //第二
  25.                
  26.                 }

  27.                 StaticDemo(){
  28.                         System.out.println("c");                //第四
  29.                 }
  30.         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
虽然执行结果相同,但顺序不对,我认为执行顺序为:静态代码块>构造方法>构造代码块,可以通过子父类继承来验证
如有不当,请指正
/*
1、静态代码块优先于mian方法执行
2、静态代码块优先于构造代码块执行
3、构造代码块优先于构造方法执行

静态代码块>构造代码块>构造方法
输出结果为:d b a c
*/

package com.staticdemo;

        public class StaticCodeDemo2
        {
                static {
                        System.out.println("d");                //第一
                }
                public static void main(String args[]){
                        StaticDemo d1=new StaticDemo();
                }
        }

        class StaticDemo
        {
                {
                        System.out.println("a");                //第三
                }

                static{
                        System.out.println("b");                //第二

                }

                StaticDemo(){
                        //这里有隐式调用,你可以自己写个子类继承就知道了
                        //super();
                        //成员属性显式初始化
                        //构造代码块
                       //下面才是构造方法中的代码  
                        System.out.println("c");                //第四
                }
        }

评分

参与人数 1技术分 +1 收起 理由
黄晓东 + 1

查看全部评分

回复 使用道具 举报
  StaticDemo(){
                        //这里有隐式调用,你可以自己写个子类继承就知道了
                        //super();
                        //成员属性显式初始化
                        //构造代码块
                       //下面才是构造方法中的代码  
                        System.out.println("c");                //第四
                }
先不写子类继承,现在此处的super()就是在调用Object类对象了,我明白你的意思
但我觉得在静态代码块完成初始化之后,要是同时存在构造代码块和构造方法,就肯定会预先加载构造代码块的
而构造方法则是在构造代码块初始化之后加载。
当加载构造方法时,分两步走,1、先初始化父类构造方法 2、再初始化本类构造方法
因为子类继承了父类,获取到了父类中内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。
而super(),那个隐式调用就是在此处进行的吧。(此处只有继承Object,没有继承其他类)
之后才初始化本类构造方法

评分

参与人数 1技术分 +1 收起 理由
黄晓东 + 1

查看全部评分

回复 使用道具 举报
zhangchao 发表于 2014-1-27 13:19
虽然执行结果相同,但顺序不对,我认为执行顺序为:静态代码块>构造方法>构造代码块,可以通过子父类继承来 ...


  StaticDemo(){
                        //这里有隐式调用,你可以自己写个子类继承就知道了
                        //super();
                        //成员属性显式初始化
                        //构造代码块
                       //下面才是构造方法中的代码  
                        System.out.println("c");                //第四
                }
先不写子类继承,现在此处的super()就是在调用Object类对象了,我明白你的意思
但我觉得在静态代码块完成初始化之后,要是同时存在构造代码块和构造方法,就肯定会预先加载构造代码块的
而构造方法则是在构造代码块初始化之后加载。
当加载构造方法时,分两步走,1、先初始化父类构造方法 2、再初始化本类构造方法
因为子类继承了父类,获取到了父类中内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。
而super(),那个隐式调用就是在此处进行的吧。(此处只有继承Object,没有继承其他类)
之后才初始化本类构造方法
这是我对此处的理解,请指教

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
周昭民 发表于 2014-1-28 12:23
StaticDemo(){
                        //这里有隐式调用,你可以自己写个子类继承就知道了
         ...

为什么说让你写个继承打印你就明白呢?因为Object类你没法打印log信息,如果能打印的话,你就明白了,之前我也是和你理解的顺序是一样的,看了毕老师的代码示例,实际打印后发现确实不是你说的顺序。我自己验证用的代码:
class ObjectInstanceDemo {
        public static void main(String[] args) {
                new Son();
        }
}

class Parent
{
        Parent() {
                System.out.println("Parent constructor run...");
                show();
        }
        void show() {
                System.out.println("Parent show run...");
        }
}
class Son extends Parent
{
        int num = 9;
        {
                System.out.println("constructor code run..." + num);
        }
        Son(){       
                //super();               
                //变量显式初始化
                //构造代码块
                System.out.println("son constructor run..." + num);
        }
        void show(){
                System.out.println("son show run..." + num);
        }
}


输出结果:
//如果不不是先执行构造方法,super()从哪执行?
Parent constructor run...


son show run...0
constructor code run...9
son constructor run...9

请指教。

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
zhangchao 发表于 2014-1-28 13:06
为什么说让你写个继承打印你就明白呢?因为Object类你没法打印log信息,如果能打印的话,你就明白了,之 ...

厉害!感谢大神的指导,确实执行结果是这样,我也觉得好惊讶,颠覆了我对加载过程的理解。可是什么log信息,能够解释一下吗,或者说,你是在哪看的毕老师的代码例子,求分享一下,谢谢
回复 使用道具 举报
周昭民 发表于 2014-1-28 14:18
厉害!感谢大神的指导,确实执行结果是这样,我也觉得好惊讶,颠覆了我对加载过程的理解。可是什么log信 ...

大神不敢当,初学而已,我是在毕老师的java35天的视频里看到的,在传智播客的官网上有下载链接
回复 使用道具 举报
zhangchao 发表于 2014-1-28 22:13
大神不敢当,初学而已,我是在毕老师的java35天的视频里看到的,在传智播客的官网上有下载链接 ...

恩,好,谢谢分享,以后有问题再请教你
回复 使用道具 举报
好好学习毕老师的视频!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马