黑马程序员技术交流社区

标题: 关于Java静态变量初始化程序的问题 [打印本页]

作者: 张超超    时间: 2012-4-16 14:13
标题: 关于Java静态变量初始化程序的问题
class StaticSuper{
    static{
        System.out.println("super static block");
    }
    StaticSuper(){
        System.out.println("super constructor");
    }
}
public class StaticTests extends StaticSuper{
    static int rand;
    static{
        rand=(int)(Math.random()*6);
        System.out.println("static block "+rand);
    }
    StaticTests(){
        System.out.println("constructor");
    }
    public static void main(String[] args){
        System.out.println("in main");
        StaticTests st=new StaticTests();
    }
}

为什么运行结果第一行输出的是
super static block
而不是
static block
作者: 罗旭维    时间: 2012-4-16 15:40
加载一个类时,它的静态初始化代码被执行。静态初始化代码段与静态变量的初始化同时进行,它们按词法顺序执行。
为什么先加载父类,可以这么理解,没有父亲就生不出儿子{:soso_e112:}。
我觉得更应该思考加注意的是静态初始化代码比main先执行。
作者: 岳民喜    时间: 2012-4-16 15:52
static{
       super();//这里默认隐式的super()语句;所以第一句一定是super static block
        rand=(int)(Math.random()*6);
        System.out.println("static block "+rand);
    }

在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
作者: 袁培育    时间: 2012-4-16 16:00
因为父类中有一个静态代码块,在父类进入内存时就可以直接执行,不用调用,当然也不会被复写(复写的是成员变量和成员函数,代码块不是两者之一不能被复写)
作者: 葛尧    时间: 2012-4-16 16:01
原来如此,子类静态代码块也隐含父类了。学习了
作者: 黑马罗坚    时间: 2012-4-16 17:16
类的初始化过程
初始化一个类须先初始化成员属性
初始化一个子类须先初始化父类
所以先执行父类的成员属性快中的打印语句
作者: 如梦初醒    时间: 2012-4-16 19:50
本帖最后由 如梦初醒 于 2012-4-16 19:52 编辑

为什么运行结果第一行输出的是
super static block
而不是
static block


我的回答所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们,初始化一个类就是为类的静态变量赋初值,静态变量的初始化有两种途径:1.在静态变量申明处;2.静态代码块中。
类的首次主动首次主动使用分六种情况:
1.Class.forName("")这个类;
2.初始化化一个类的子类;
3.访问某个类或接口的静态变量,或者对该静态变量赋值;
4.调用类的静态方法
5.调用类的构造方法(也就是new出一个对象);
6.启动类(如:包含main方法的那个类);
基于以上分析, StaticTests含有main方法为启动类,JVM认为这是对 StaticTests类的首次主动使用,
会对其进行初始化化,但这个类继承于StaticSuper类,那么JVM将首先初始化StaticSuper这个类,
初始化StaticSuper这个类就会执行初始化语句 static{
        System.out.println("super static block");
    }

作者: 邓斌    时间: 2012-4-16 20:20
可以看看。
http://bbs.itheima.com/forum.php?mod=viewthread&tid=11637
此贴楼主代码很有验证性。。本人回复也不错。。呵呵。
作者: 蒋亮    时间: 2012-4-16 22:16
子类继承父类,重用父类的方法、属性,也就是说父类有的子类都有,先继承父类的再扩展自己的,而静态代码块是按静态代码块的顺序执行的,所以第一行打印出来的是super static block




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