黑马程序员技术交流社区

标题: 哪个先执行的问题 [打印本页]

作者: 武超    时间: 2011-12-1 12:36
标题: 哪个先执行的问题
本帖最后由 武超 于 2011-12-3 15:14 编辑

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

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

    Test()
    {System.out.println("c");}
}
这段程序是怎样执行的,为什么?在内存中是怎样实现的呢?谢谢
作者: 侯伟浩    时间: 2011-12-1 12:48
输出结果为:a,b,c
作者: 李晓斌    时间: 2011-12-1 13:04
晕,你这个程序连main方法都没有,不能运行的。但是,静态代码块是优先于主方法的执行,
所以即使没有main方法,你这个程序还是会输出静态方法中的a。
另外,静态块优先于构造函数的执行,而且只执行一次!
再另外,构造代码块是给对象进行初始化的,对象一建立就运行,而且优于构造函数执行。


作者: xiaolij3s    时间: 2011-12-1 13:22
静态代码块是优先于主方法的执行,所以你调用方法时候先输出a,而且只执行一次。
然后构造代码块是给对象进行初始化的,对象一建立就运行,而且优于构造函数执行。
所以输出b,然后c
作者: 张海兵    时间: 2011-12-1 17:11
这个涉及到对象,类的加载及运行问题,首先会讲类文件:test加载到内存中,执行静态代码块,后随着对象的建立,先加载构造代码块!
作者: 李盈科    时间: 2011-12-1 18:33
静态代码块 执行顺序优先于构造方法 所以先输出ab 然后是C  但是static块 只加载一次
作者: 翟友伟    时间: 2011-12-1 18:40
楼上正解,具体可以看 毕向东 第六日 视频!~~
http://dl.dbank.com/c0g0l3zr6g  视频下载 面向对象---静态函数部分
作者: 翟友伟    时间: 2011-12-1 18:48
加载  Test .class  文件到内存中
实行类中的 Static代码,给类初始化
  System.out.println("a");}

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

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

加上主  main()运行


作者: 刘海涛    时间: 2011-12-1 22:08
本帖最后由 刘海涛 于 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
其实楼主对于这种问题可以暂时先稍微记下就可以了,知道有这么回事,到后面的学习中你可以慢慢体会。

这些知识可在以后的单例,初始化应用程序,缓存等等中得到更深刻的了解。
作者: 许邦存    时间: 2011-12-1 22:08
没有主方法程序是运行不了的,首先要让程序运行得加主方法;public static void main(String[] args)
{},如果里面什么都不写输出为a,因为静态代码不和对像联系在一起,可以独立运行,好像没有构造代码块这一说,构造函数是实例化时用到的函数,如果在主函数中加上new Test(); ,静态代码块会先执行,再到非静态代码块,最后是构造函数,那么函数输出为 a b c,具体的内存不太清楚呵呵,不过new出来的对象时在堆内存中;刚学,个人的理解,可能有不正确的地方,大家一起讨论。
作者: 赵燕燕    时间: 2011-12-2 09:34
本帖最后由 赵燕燕 于 2011-12-2 15:45 编辑

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

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


什么时候会加载类?
        使用到类中的内容时加载:1.创建对象:new StaticCode();
                                2.使用类中的静态成员:StaticCode.num=9;  StaticCode.show();
                                3.在命令行中运行:java StaticCode
作者: fly51888    时间: 2011-12-2 11:03
本帖最后由 fly51888 于 2011-12-2 11:03 编辑

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

所以输出结果是 a.





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2