深入 java 初始化
【程序编程相关:多层数据库开发十三:剖析几个数据库应用程】关于java 初始化,有多文章都用了很大篇幅的介绍.经典的<<thinking in java>>更是用了专门的 【推荐阅读:多层数据库开发十二:使用数据控件 】
本文以作者对jvm的理解与自己的经验,对java的初始化做一个比深入的说明,由于作者有水平限制, 【扩展信息:多层数据库开发十四:剖析几个MIDAS示】
一章来介绍java初始化.但在大量有代码实例后面,感觉上仍然没有真正深入到初始化的本质. 以及jdk各实现版本的变化,可能仍然有不少错误与缺点.欢迎行家高手赐教. 要深入了解java初始化,我们无法知道从程序流程上知道jvm是按什么顺序来执行的.了解jvm的执行 机制与堆栈跟踪是有效的手段.可惜的是,到目前为止.jdk1.4与jdk1.5在javap功能上却仍然存在 着bug.所以有些过程我无法用实际的结果向你证明两种相反的情况(但我可以证明那确实是一个bug)<<thinking in java>>(第三版)在第四章一开始的时候,这样来描述java的初始化工作:
以下译文原文: 可以这样认为,每个类都有一个名为initialize()的方法,这个名字就暗示了它得在使用之前调用,不幸 的是,这么做的话,用户就得记住要调用这个方法,java类库的设计者们可以通过一种被称为构造函数的 特殊方法,来保证每个对象都能得到被始化.如果类有构造函数,那么java就会在对象刚刚创建,用户还来 不及得到的时候,自动调用那个构造函数,这样初始化就有保障了.我不知道原作者的描述与译者的理解之间有多大的差异,结合全章,我没有发现两个最关键的字"<clinit>"
与"<init>".至少说明原作者与译者并没有真正说明jvm在初始化时做了什么,或者说并不了解jvm的初始化 内幕,要不然明明有这两个方法,却为什么要认为有一个事实上并不存在的"initialize()"方法呢? "<clinit>"与"<init>"方法在哪里? 这两个方法是实际存在而你又找不到的方法,也许正是这样才使得一些大师都犯晕.加上jdk实现上的一 些bug,如果没有深入了解,真的让人摸不着北.现在科学体系有一个奇怪的现象,那么庞大的体系最初都是建立在一个假设的基础是,假设1是正确的,
由此推导出2,再继续推导出10000000000.可惜的是太多的人根本不在乎2-100000000000这样的体系都 是建立在假设1是正确的基础上的.我并不会用“可以这样认为”这样的假设,我要确实证明"<clinit>" 与"<init>"方法是真真实实的存在的:package debug;
public class mytest{ static int i = 100/0; public static void main(string[] args){ ssytem.out.println("hello,world!"); } }执行一下看看,这是jdk1.5的输出:
java.lang.exceptionininitializererror
caused by: java.lang.arithmeticexception: / by zero at debug.mytest.<clinit>(test.java:3) exception in thread "main"请注意,与其它方法调用时产生的异常一样,异常被定位于debug.mytest的<clinit>.
再来看:package debug;
public class test { test(){ int i = 100 / 0; } ... 下一页