快速业务通道

解析Java类和对象的初始化过程 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-21

解析Java类和对象的初始化过程

时间:2011-01-05

本文主要对类和对象初始化全过程进行分析,通过一个实际问题引入,将源代码转换成 JVM 字节码后,对 JVM 执行过程的关键点进行全面解析,并在文中穿插入了相关 JVM 规范和 JVM 的部分内部理论知识,以理论与实际结合的方式介绍对象初始化和类初始化之间的协作以及可能存在的冲突问题。

问题引入

近日我在调试一个枚举类型的解析器程序,该解析器是将数据库内一万多条枚举代码装载到缓存中,为了实现快速定位枚举代码和具体枚举类别的所有枚举元素,该类在装载枚举代码的同时对其采取两种策略建立内存索引。由于该类是一个公共服务类,在程序各个层面都会使用到它,因此我将它实现为一个单例类。这个类在我调整类实例化语句位置之前运行正常,但当我把该类实例化语句调整到静态初始化语句之前时,我的程序不再为我工作了。 下面是经过我简化后的示例代码:

[清单一]

package com.ccb.framework.enums; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class CachingEnumResolver {   //单态实例 一切问题皆由此行引起   private static final CachingEnumResolver SINGLE_ENUM_RESOLVER = new CachingEnumResolver();   /*MSGCODE->Category内存索引*/   private static Map CODE_MAP_CACHE;   static {    CODE_MAP_CACHE = new HashMap();    //为了说明问题,我在这里初始化一条数据    CODE_MAP_CACHE.put("0","北京市");   }   //private, for single instance   private CachingEnumResolver() {    //初始化加载数据 引起问题,该方法也要负点责任    initEnums();   }   /** * 初始化所有的枚举类型 */   public static void initEnums() {    // ~~~~~~~~~问题从这里开始暴露 ~~~~~~~~~~~//    if (null == CODE_MAP_CACHE) {     System.out.println("CODE_MAP_CACHE为空,问题在这里开始暴露.");     CODE_MAP_CACHE = new HashMap();    }    CODE_MAP_CACHE.put("1", "北京市");    CODE_MAP_CACHE.put("2", "云南省");    //..... other code...   }   public Map getCache() {    return Collections.unmodifiableMap(CODE_MAP_CACHE);   }   /** * 获取单态实例 * * @return */   public static CachingEnumResolver getInstance() {    return SINGLE_ENUM_RESOLVER;   }   public static void main(String[] args) {    System.out.println(CachingEnumResolver.getInstance().getCache());   } }

想必大家看了上面的代码后会感觉有些茫然,这个类看起来没有问题啊,这的确属于典型的饿汉式单态模式啊,怎么会有问题呢?

是的,他看起来的确没有问题,可是如果将他 run 起来时,其结果是他不会为你正确 work。运行该类,它的执行结果是:

解析Java类和对象的初始化过程(2)

时间:2011-01-05

[清单二]

CODE_MAP_CACHE为空,问题在这里开始暴露.{0=北京市}

我的程序怎么会这样?为什么在 initEnum() 方法里 CODE_MAP_CACHE 为空?为什么我输出的 CODE_MAP_CACHE 内容只有一个元素,其它两个元素呢????!!

看到这里,如果是你在调试该程序,你此刻一定觉得很奇怪,难道是我的 Jvm 有问题吗?非也!如果不是,那我的程序是怎么了?这绝对不是我想要的结果。可事实上无论怎么修改 initEnum() 方法都无济于事,起码我最初是一定不会怀疑到问题可能出在创建 CachingEnumResolver 实例这一环节上。正是因为我太相信我创建 CachingEnumResolver 实例的方

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号