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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 乔青山 中级黑马   /  2014-2-26 12:24  /  2263 人查看  /  9 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何伟超 于 2014-2-26 21:38 编辑

毕老师在讲到静态类的时候提了这么个知识点,意思是说:这句代码Person p = null;看似加载类,但是因为什么都没做,所以实际上是不加载类的,自然就不执行静态代码块了。

但是,自己写了个小程序后:
public class TestStaticCon {
    public static int a = 0;

    static {
        a = 10;
        System.out.println("静态代码块执行a=" + a);
    }

    {
        a = 8;
        System.out.println("非静态代码块执行a=" + a);
    }

    public TestStaticCon() {
        this(a);//打印10,为什么?
            System.out.println(a);
        System.out.println("无参构造方法执行a=" + a);
    }

    public TestStaticCon(int n) {
        System.out.println(n);
        System.out.println(a);

    }

    public static void main(String[] args) {
        TestStaticCon tsc = null;
        System.out.println("!!!!!!!!!!!!!!!!!!!!!");
        tsc = new TestStaticCon();
    }
}


运行结果是:
静态代码块执行a=10
!!!!!!!!!!!!!!!!!!!!!
非静态代码块执行a=8
10
8
8
无参构造方法执行a=8


两个问题:
1. TestStaticCon tsc = null;这句代码打印出了结果,那这句代码到底急啊不加载类?
2. this(a);这句代码调用有参构造函数,结果打印10,为什么?

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

9 个回复

倒序浏览
觉得原因是:
1、静态代码块先执行,输出10
2、空参数构造方法执行立马调用了有参构造方(这里不会执行构造代码块)将10传了过去
3、带参构造方法执行时,(这里才会执行构造代码块)打印n为10,a为8
             参考子调用父构造方法就知道了。
4、执行空能构造方法的输出8

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
第一个问题:TestStaticCon tsc = null;不会加载类。你看到打印了静态代码块运行是因为JVM运行main方法时加载的。
class Test3 {
        public static void main(String[] args) {
                TestStaticCon tsc = null;
                System.out.println("!!!!!!!!!!!!!!!!!!!!!");
                tsc = new TestStaticCon();
        }
}

将main方法单独提出来运行结果就变了:
!!!!!!!!!!!!!!!!!!!!!
静态代码块执行a=10
非静态代码块执行a=8
10
8
8
无参构造方法执行a=8

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
e.c 发表于 2014-2-26 14:39
第一个问题:TestStaticCon tsc = null;不会加载类。你看到打印了静态代码块运行是因为JVM运行main方法时加 ...

哦~明白了,谢谢
回复 使用道具 举报
1、静态优先于类加载,故    静态代码块执行a=10
2、tsc = new TestStaticCon();调用无参构造函数,但是无参构造函数第一行调用有参构造函数,所以先不加载代码   块
3、调用有参构造函数,此时加载代码块,a=8,但是由于构造函数传入实参n=10,所以先输出10,后输出8
4、之后再回到无参构造函数System.out.println(a);输出结果8,
5、最后执行System.out.println("无参构造方法执行a=" + a);

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

回复 使用道具 举报
e.c 发表于 2014-2-26 14:31
觉得原因是:
1、静态代码块先执行,输出10
2、空参数构造方法执行立马调用了有参构造方(这里不会执行构造 ...

嗯。。有道理,唯一不明白的地方是为什么调用空参构造器的时候不执行构造代码块
回复 使用道具 举报
e.c 中级黑马 2014-2-26 15:14:27
7#
本帖最后由 e.c 于 2014-2-26 15:15 编辑
乔青山 发表于 2014-2-26 15:01
嗯。。有道理,唯一不明白的地方是为什么调用空参构造器的时候不执行构造代码块 ...

如果子类没有指定调用父类构造方法的情况下,会默认调用父类的空参构造方法。再看下面情况:
如果子类空参调用了另一个带参的构造方法的话,空参构造方法也不会调用父类构造方法。而是在另一个带参的构造方法里才会去调用父类的构造方法。一定会调用到父类的构造方法。
而构造代码块是在调用完父类构造方法后才执行的。所以应该是这个样子。
基础视频有讲好像。
回复 使用道具 举报
e.c 发表于 2014-2-26 15:14
如果子类没有指定调用父类构造方法的情况下,会默认调用父类的空参构造方法。再看下面情况:
如果子类空参 ...

哦~明白了。。这个类是object的子类,所以需要object的构造代码块和构造函数执行了才会执行这个类的构造代码块。而因为无参构造器调用了有参构造器,所以super()是在有参构造器中,所以在调用有参构造器的时候a的值仍然是10.
是这个思想不
回复 使用道具 举报
e.c 中级黑马 2014-2-26 16:17:45
9#
嗯。我记得基础视频里说到过
子类构造方法里会先执行父类构造方法,执行完父类构造方法后执行显示初始化,再执行构造代码块。然后子类构造方法才继续向下执行
回复 使用道具 举报
e.c 发表于 2014-2-26 16:17
嗯。我记得基础视频里说到过
子类构造方法里会先执行父类构造方法,执行完父类构造方法后执行显示初始化, ...

我还没看到继承,看到那我会留意一下。
不过你这个想法感觉很有道理,多谢~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马