- 浏览: 81982 次
- 性别:
- 来自: 宁德
文章分类
最新评论
-
wizard945:
350850895@qq.com 感谢楼主
SSI的整合七部曲 -- 1、Struts2实现通过JDBC的CURD -
火红火红火箭迷:
请教一下,我的不能安装在在C盘的program files文 ...
分享MyEclipse安装及安装报错的解决方法 -
kdslafie:
没有具体的例子,只大概说了配置,一点都不明了。
Eclipse和MyEclipse插件的管理(以安装FatJar、UMLet作为示例说明) -
瘋叻ハ.兩:
Super丶曼 写道不好用啊,纠结啊。换了家公司,一直在用id ...
分享MyEclipse安装及安装报错的解决方法 -
Super丶曼:
不好用啊,纠结啊。
分享MyEclipse安装及安装报错的解决方法
既然谈到类的初始化,那就不得不把VM(Virtual Machine,虚拟机)先做个简单的介绍...
VM,是Java程序运行的核心。它是不可视的,也就是说你在你的机器上根本找不到它。那么它到底是怎么产生的呢?其实它只是一个dll格式文件(全称是jvm.dll,该文件隐藏在jre目录下)。初始化VM的过程:java命令解释*.class文件时 ----> 通过环境变量找到JRE目录并产生JRE ----> 在JRE目录下,寻找jvm.dll文件,并初始化一个jvm (VM的更详细介绍请自行下载观看JVM工作原理)
当我们需要运行一个类时,过程且看图片“类的生命周期”。 本文只着重介绍到“初始化”一步,并尽可能的用代码证明得出的结论。 重申:类的连接分为验证、准备、解析
1、装载
也称类的加载。它是指将类的class文件(本地磁盘或者网络上)加载至VM内存中,并为之创建一个对应的java.lang.Class对象。(这部分内容本人正在消化中,代码消化完贴出...)2011.5.29 补上
加载类的加载器有三种:
1、Bootstrap ClassLoader:根类加载器,也称引导类加载器。它是VM自动实现的,代码是用c语言实现的,所以你在IDE中是找不到它的源代码滴。 它负责加载jdk中的系统类,加载Java的核心类如String。
2、Extension ClassLoader:扩展类加载器。它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统指定的目录)中JAR的类包。
3、System ClassLoader:系统类加载器。它负责在JVM启动时,加载来自命令java -classpath或者java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。一般都认为系统类加载器是加载应用程序第一个类的加载器
代码如下
package com.ClassTests; /************************************************** * * @author: 瘋叻ハ.兩 * @create-time: 2011-5-22 下午07:13:14 * @revision: 1.0 * @purpose: 类的加载 * **************************************************/ public class LoadClass { public static void main(String[] args){ // 查看根加载器加载的类的路径 // URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); // for(int i = 0; i < urls.length; i++){ // System.out.println(urls[i].toExternalForm()); // } // 获取JVM的名称 System.out.println("JVM名称是:"+System.getProperty("java.vm.name")); // System.out.println("Java 类路径:"+System.getProperty("java.class.path")); // System.out.println("加载库时搜索的路径列表:"+System.getProperty("java.library.path")); // System.out.println("用户的主目录:"+System.getProperty("user.home")); // System.out.println("用户的当前工作目录:"+System.getProperty("user.dir")); // 获取系统类的加载器 ClassLoader cl = ClassLoader.getSystemClassLoader(); System.out.println("系统的类加载器是:"+cl); // 获取加载器的类名 System.out.println("类加载器的类名是:"+cl.getClass()); // 获取扩展类加载器,因为是系统类加载器的父类 ClassLoader clp = cl.getParent(); System.out.println("系统的类加载器的父类加载器是:"+clp); // 获取扩展类加载器的类名 System.out.println("系统的类加载器的父类加载器的类名是:"+clp.getClass()); // 获取根类加载器(结果是null,所以如果进一步获取类名,报NullPoint异常) System.out.println("根类加载器是:"+clp.getParent()); } }
运行结果:JVM名称是:Java HotSpot(TM) Client VM
系统的类加载器是:sun.misc.Launcher$AppClassLoader@19821f
类加载器的类名是:class sun.misc.Launcher$AppClassLoader
系统的类加载器的父类加载器是:sun.misc.Launcher$ExtClassLoader@addbf1
系统的类加载器的父类加载器的类名是:class sun.misc.Launcher$ExtClassLoader
根类加载器是:null
分 析: Java程序执行的流程:*.class --> 通过环境变量找到JRE目录 --> 在该目录找到jvm.dll --> JVM初始化 --> 产生BootstrapLoader --> 载入ExtClassLoader --> 载入AppClassLoader --> 装载*.class --> 字节码校验 --> 解析器执行
2、验证
验证阶段是用于检验被加载的类是否有正确的内部结构,并和其他类协调一致(毫无代码可言)
3、准备
准备阶段是负责给类的静态属性分配内存,并设置默认初始值,而不是初始化(注意区别)。
代码如下
package com.ClassTests; /************************************************** * * @author: 瘋叻ハ.兩 * @create-time: 2011-5-21 下午08:21:25 * @revision: 1.0 * @purpose: 探秘类的准备阶段发生的事情 * ***************************************************/ public class ClassReady { static{ b = 4; } static int b; public static void main(String[] args) { System.out.println(b); } }
运行结果:4
分 析 :首先第一个问题,为什么在静态初始块中b没有定义类型不报错?其次,结果为什么是4,而不是int的默认值0? 其实正是在类的准备阶段,VM为类的静态属性分配内存,使得内存中已然存在了b变量,所以在类的初始化阶段,虽未给b定义类型,但系统也不报错。接下来进行类的初始化,只有静态代码块的初始化,所以,因此结果为4,证明了类在准备阶段只为类的静态属性分配内存,而并没有执行它的成员动作。 4、解析 解析阶段是将类的二进制数据中的符号引用替换成直接引用。(也无代码可言) 5、类的初始化 类的初始化阶段,VM负责对类进行初始化,主要是对类属性(静态属性)进行初始化,方式有2:(1)声明静态属性时指定初始值;(2)使用静态初始化块为静态属性指定初始值。 代码如下 package com.ClassTests;
/**************************************************
*
* @author: 瘋叻ハ.兩
* @create-time: 2011-5-21 下午08:40:58
* @revision: 1.0
* @purpose: 类的初始化方式
*
***************************************************/
public class ClassInition {
static int a = 5; // 声明时指定初始值
static int b;
static int c = 7;
static{
b = 6; // 声明时未指定,可以在静态初始块中补上
c = 8; // 如果两种都有,结果取后一个
}
public static void main(String[] args) {
System.out.println("a的初始化值是 "+a);
System.out.println("b的初始化值是 "+b);
System.out.println("c的初始化值是 "+c);
}
}
运行结果:a的初始化值是 5
b的初始化值是 6
c的初始化值是 8
分 析 :一切都按部就班初始化着
5、实例初始化
在进行玩类的初始化,就会进行实例初始化。过程与类的初始化不相上下。
代码如下:
package com.ClassTests; /************************************************** * * @author: 瘋叻ハ.兩 * @create-time: 2011-5-21 下午01:27:04 * @revision: 1.0 * @purpose: 简析类的生命周期及类的初始化 * ***************************************************/ /************************************************** * * @author: 瘋叻ハ.兩 * @create-time: 2011-5-21 下午02:25:46 * @revision: 1.0 * @purpose: 类的实例化 * ***************************************************/ class Parents{ public Parents(){ System.out.println("---此时调用了子类的构造方法,父类的初始化开始..."); } } public class ClassLife extends Parents { private static int c; public ClassLife(){ //super(); //有无super()结果一致,说明程序默认优先初始化直接父类,然后再子类。如果需要显示调用,super()必须放在第一句 System.out.println("---此时调用了子类构造方法,子类的初始化开始..."); } // 静态初始化块 static { System.out.println("---执行了类的初始化..."); System.out.println(c); } // 初始化块 { System.out.println("---执行了对象的初始化块..."); // 问题1: 为什么没有声明b,而可以使用4。 b = 4; } int b; public static void main(String[] args) { ClassLife cl = new ClassLife(); System.out.println(cl.b); // 对象属性的初始化与类的属性初始化一致 } }
运行结果:---执行了类的初始化...
---此时调用了子类的构造方法,父类的初始化开始...
---执行了对象的初始化块...
---此时调用了子类构造方法,子类的初始化开始...
4
分 析 : 认真看上面的类的初始化
最后归纳下对象创建过程发生的事:
给类的属性在分配内存 ----> 初始化类的属性 ----> 给对象属性分配内存 ----> 在初始块中初始化对象属性 ---->如果有父类,优先构造初始化父类 ----> 调用子类的构造器,创建对象。
发表评论
-
Oracle10G -- 图文介绍JNDI环境的搭建
2012-04-12 15:57 1419本文旨在图文介绍以Oracle为数据库的JNDI的 ... -
Oracle10G -- 图文介绍JDBC环境的搭建
2012-04-11 13:19 1873本文旨在图文介绍搭建以Oracle为数据库的JDB ... -
Java中、英文 1.6API(附截图)
2011-10-05 14:15 1500API的作用不再言表。如题,直接附上截图 j ... -
面向接口 ---- 简单工厂模式和命令模式
2011-09-14 15:40 1336初次学完抽象类和接口的童鞋,看多了“面向接口编程& ... -
final,助你排除不稳定
2011-09-12 18:33 1180【友情提示, ... -
造型(Casting) --- 多态的延续
2011-09-07 13:57 1027于此,在次申明个人觉得把握多态的最重要的一点:( ... -
Java进阶 ---- 多态(Polymorphism)
2011-09-06 21:28 3204从前面的继承(Inheritance)到比较thi ... -
this 和 super
2011-09-06 14:15 956一、this 和 super ... -
Java进阶 ---- 封装
2011-05-30 22:37 944封装,是面向对象三大特征之一。它指的是将对象的状态 ... -
Java起航 ---- 继承
2011-05-29 20:28 890一、Inheritance ... -
Java起航 ---- 方法
2011-05-20 21:38 967方法,是类 ... -
Java起航 ---- 类的变量
2011-05-18 22:40 874续前一篇的介绍,本篇主要介绍各种变量的使用。它的分类,请 ... -
Java起航 ---- 类
2011-05-16 20:14 732没有特别的, ... -
Java前奏
2011-03-25 21:00 860差不多有一年没碰JavaSE了,这篇也是寒假回头复 ...
相关推荐
让追求承载梦想起航--广电网络演讲稿.doc
2020学年高中历史第4单元工业文明冲击下的改革第14课日本近代化的起航--明治维新随堂练习.pdf
度QDII基金投资策略:岁寒添防御,征途再起航-0107-国金证券-45页.pdf
交通运输行业2021年投资策略:拨云见日,重新起航-20201230-长城证券-31页.pdf
有色金属行业深度报告:2019,黄金新周期的起航-20190624-银河证券-31页.pdf
shopex 商务系列模板-梦想起航-ShopEx4[1].8
软体家居行业深度报告:软体家居内外兼修,格局优化看好龙头扬帆起航-20210302-浙商证券-14页.pdf
佩蒂股份 - 宠物咬胶领军者,国内扬帆起航-210111_宠物行业研究报告
证券行业科创板专题报告之二:推动科技创新成果转化,新时代专业投行起航-20190407-中银国际-42页.pdf
中银证券-计算机行业数据要素深度一:拐点将至,数据要素全面起航-230528.pdf
生物医药行业专题报告:科创板撬动万亿级医药创新市场,中国版“纳斯达克”拔锚起航-0331-平安证券-35页.pdf
【起航-远望-杜跃进.pdf】的文件主题主要围绕着移动应用安全和相关的信息安全领域展开,尤其强调了在快速发展的互联网环境中,如何应对业务、数据、云、移动等方面的安全挑战。以下是根据标题、描述和标签提取的相关...
中小盘:宠物医疗再整合,连锁超千店的新瑞鹏集团起航-国盛证券-190127_宠物行业研究报告.pdf
【蚂蚁金服】是金融科技领域的巨头,自2004年支付宝成立以来,它已发展成为一个包含多重业务和技术的综合平台。蚂蚁金服的核心优势在于其...未来,它将在去金融化趋势下,依靠技术驱动,继续在新的市场领域中扬帆起航。
然而,由于物联网市场持续的碎片化,传统的“封闭设计”处理器模式难以适应细分领域多样化的需要,维持低成本的同时又满足特定需求变得异常困难。 报告接着提出了处理器开源发展模式的可能性,参考互联网时代软件...
《新时代城镇化系列研究(一):新时代城镇化起航》是由华泰证券在2019年12月17日发布的行业研究报告。这份报告聚焦于中国城镇化进程的新阶段及其对经济社会发展的影响,揭示了新时代城镇化的新特点、挑战与机遇。 ...
### Java起航之旅 #### 一、Java发展简史与命名由来 Java语言的起源可以追溯至1990年代初期,最初是由Sun Microsystems公司的James Gosling带领团队开发的一种名为“Oak”的语言。这个名字源自于James Gosling...