static块到底什么时候执行?(转自javaeye上面的讨论)

看了这帖子,发现自己对Inside  JVM这本书并未吃透,还得加强,原贴地址:http://forum.javaeye.com/viewtopic.php?t=11003&postdays=0&postorder=asc&start=0

"java深度历险"一书在讲解“类装载”的一章中,举了以下的例子:
引用:

java代码: 

public interface Assembly {
    public void start ( );
}

public class Word implements Assembly {
    static {
        System. out. println ("Word static initialization!" );
    }   

    public  void start ( ) {
        System. out. prinlnt ("Word starts" );
    }
}

public class Office {
    public static void main ( String args [ ] ) throws Exception {
        Office off = new Office ( );
        System. out. println ("类别准备载入" );
        Class c = Class. forName (args [ 0 ], true,off. getClass ( ). getClassLoader ( ) );
        System. out. println ("类别准备实例化" );
        Object o = c. newInstance ( );
        Object o2= c. newInstance ( );
    }
}

执行java Office Word,运行结果如下:
“Loaded Office”
“类别准备载入”
“Loaded Accembly”
“Loaded Word””
“Word static initialization”
“类别准备实体化”。


但是如果将Office.java中Class.forName(args[0],true,off.getClass().getClassLoader())中的true变为false,再执行java Office Word结果显示为:
“Loaded Office”
“类别准备载入”
“Loaded Accembly”
“Loaded Word””
“类别准备实体化”
“Word static initialization”。


显然两次红字部分顺序相反,及static块执行的顺序不同。此书作者提出了原因,原文:
引用:
“过去很多java书上提到静态初始化(static initializion block)时,都会说静态初始化区块只是在类第一次载入的时候才会被调用仅仅一次。可是上面输出却发现即使类被载入了,其静态初始化区块也没有被调用,而是在第一次调用newInstance方法时,静态初始化块才被真正调用,应该改成-静态初始化块只是在类被第一次实体化的时候才会被仅仅调用一次。”


其实,该书作者的上述描述有误。通过一个试验,就可以看出谬误所在。
java代码: 

public class TestA {
    static {
        System. out. println ("Static block executed!" );
    }   
}

public class Test {
    public static void main ( String args [ ] ) {
       Test test = new Test ( );
        Class. forName ("TestA", true,test. getClass ( ). getClassLoader ( ) );
    }
}

运行一下,相信大家一定可以看到,“Static block executed!”的输出。这与
引用:
而是在第一次调用newInstance方法时,静态初始化块才被真正调用
的说法矛盾。

其实我想事实是这样的:
一个类的运行,JVM做会以下几件事情 1、类装载 2、链接 3、初始化 4、实例化;而初始化阶段做的事情是初始化静态变量和执行静态方法等的工作。所以,当Class.forName(args[0],true,off.getClass().getClassLoader());中的true变为false的时候,就是告诉JVM不需再load class之后进行initial的工作。这样,将initial的工作推迟到了newInstance的时候进行。所以,static块的绝对不是什么“只是在类被第一次实体化的时候才会被仅仅调用一次”,而应该是在类被初始化的时候,仅仅调用一次。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值