类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来分析的文章更是鲜有所见。
本文主要对类和对象初始化全过程进行分析,通过一个实际问题引入,将源代码转换成 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类和对象的初始化过程
来源:商务互联
作者:佚名
时间:2008-03-31
点击:
0
最新评论共有 0 位网友发表了评论
查看所有评论
发表评论
- 栏目列表
-
热点关注
- Java:数组
- java初学者实践教程9-数
- 关于JAVA匿名内部类的一点
- 对InputStream和OutputStr
- try catch finally与retur
- 使用SimpleDateFormat必须
- 配制Spring事务和JdbcTemp
- Java中的static的含义
- Java新手上路大全(初学者
- 利用JBuilder2005开发Web
- java与c#中二维数组的区别
- 利用java做一个简单的计算
- java初学者实践教程24-反
- 编程基础:Java中的数据结
- java中文件操作大全
- Java数据结构---基于数组
- 详细解析如何进行构件开发
- Java入门--漫谈Java程序
- 使用SDO跟踪XML数据的变化
- 初探Java本地接口工作方式

