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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 武超 黑马帝   /  2011-12-1 12:36  /  3574 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 武超 于 2011-12-3 15:14 编辑

在一个类中有,构造代码块,静态代码块,以及构造函数如:
class  Test
{
     static
    {System.out.println("a");}

    {System.out.println("b");}

    Test()
    {System.out.println("c");}
}
这段程序是怎样执行的,为什么?在内存中是怎样实现的呢?谢谢

评分

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

查看全部评分

11 个回复

倒序浏览
输出结果为:a,b,c

评分

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

查看全部评分

回复 使用道具 举报
晕,你这个程序连main方法都没有,不能运行的。但是,静态代码块是优先于主方法的执行,
所以即使没有main方法,你这个程序还是会输出静态方法中的a。
另外,静态块优先于构造函数的执行,而且只执行一次!
再另外,构造代码块是给对象进行初始化的,对象一建立就运行,而且优于构造函数执行。

评分

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

查看全部评分

回复 使用道具 举报
静态代码块是优先于主方法的执行,所以你调用方法时候先输出a,而且只执行一次。
然后构造代码块是给对象进行初始化的,对象一建立就运行,而且优于构造函数执行。
所以输出b,然后c

评分

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

查看全部评分

回复 使用道具 举报
这个涉及到对象,类的加载及运行问题,首先会讲类文件:test加载到内存中,执行静态代码块,后随着对象的建立,先加载构造代码块!

评分

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

查看全部评分

回复 使用道具 举报
静态代码块 执行顺序优先于构造方法 所以先输出ab 然后是C  但是static块 只加载一次

评分

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

查看全部评分

回复 使用道具 举报
翟友伟 黑马帝 2011-12-1 18:40:04
7#
楼上正解,具体可以看 毕向东 第六日 视频!~~
http://dl.dbank.com/c0g0l3zr6g  视频下载 面向对象---静态函数部分
回复 使用道具 举报
翟友伟 黑马帝 2011-12-1 18:48:51
8#
加载  Test .class  文件到内存中
实行类中的 Static代码,给类初始化
  System.out.println("a");}

    {System.out.println("b");}
在堆内存开辟空间
对对象进行狗仔代码块 初始化
Test()
    {System.out.println("c");}

结果为:  a
               b
               c
static部分的代码 单独在内存中存在   (方法区)

加上主  main()运行

评分

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

查看全部评分

回复 使用道具 举报
刘海涛 黑马帝 2011-12-1 22:08:26
9#
本帖最后由 刘海涛 于 2011-12-1 22:10 编辑

楼主您这个问题,是一个死规律的,java语言已经规定了,所以你只需要了解下java如何从硬盘把java类Load到内存如何创建实例。
下面简单写下java创建实例步骤:
1、类只有在使用New调用创建的时候才会被JAVA类装载器装入,生成Class对象
2、JAVA类首次装入时,会对静态成员变量或方法进行一次初始化
3、创建类实例时,首先按照父子继承关系进行初始化
4、类实例创建时候,首先初始化块部分先执行,然后是构造方法;
5、本类构造方法初始化会先调用父类的构造方法。

下面图是您这个类加载简单的序列图:
static
    {System.out.println("a");}//static代码块

    {System.out.println("b");}//初始化代块

    Test()
     {System.out.println("c");} //构造方法



结果是:a  b c
其实楼主对于这种问题可以暂时先稍微记下就可以了,知道有这么回事,到后面的学习中你可以慢慢体会。

这些知识可在以后的单例,初始化应用程序,缓存等等中得到更深刻的了解。

评分

参与人数 1技术分 +2 收起 理由
admin + 2 赞一个!

查看全部评分

回复 使用道具 举报
没有主方法程序是运行不了的,首先要让程序运行得加主方法;public static void main(String[] args)
{},如果里面什么都不写输出为a,因为静态代码不和对像联系在一起,可以独立运行,好像没有构造代码块这一说,构造函数是实例化时用到的函数,如果在主函数中加上new Test(); ,静态代码块会先执行,再到非静态代码块,最后是构造函数,那么函数输出为 a b c,具体的内存不太清楚呵呵,不过new出来的对象时在堆内存中;刚学,个人的理解,可能有不正确的地方,大家一起讨论。

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 赵燕燕 于 2011-12-2 15:45 编辑

静态代码块:用于给类初始化,类加载时就会被加载执行,只加载一次。
构造代码块:用于给所有对象进行统一初始化的。只要建立对象该部分就会被执行,且优先于构造函数。
构造函数:给对应对象初始化的,建立对象时,选择相应的构造函数初始化对象。

创建对象时,三者被加载执行顺序:静态代码块--->构造代码块--->构造函数


什么时候会加载类?
        使用到类中的内容时加载:1.创建对象:new StaticCode();
                                2.使用类中的静态成员:StaticCode.num=9;  StaticCode.show();
                                3.在命令行中运行:java StaticCode

评分

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

查看全部评分

回复 使用道具 举报
fly51888 黑马帝 2011-12-2 11:03:14
12#
本帖最后由 fly51888 于 2011-12-2 11:03 编辑

java类加载顺序:先父类的static成员变量->子类的static成员变量->父类的成员变量->父类构造函数->子类成员变量->子类构造函数。记住这个顺序一般就可以了。
所以虚拟机在加载上述类时,就会执行该类的静态代码块,如下代码:
static
    {System.out.println("a");}

所以输出结果是 a.

评分

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

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马