JVM之类加载器上篇
首先我们先看一个示例程序:
package com.tfdd.test; /**
* @desc 类加载校验
* @author chenqm
* @date 2016年2月2日
*/
class Singleton{
private static Singleton singleton = new Singleton();
public static int count1 ;
public static int count2 = 0; private Singleton(){
count1++;
count2++;
} public static Singleton getInstance(){ return singleton;
} }
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.count1);
System.out.println(singleton.count2);
}
}
猜猜输出的结果是什么?据说80%的java程序猿都会犯的错误!
1
0
就是这样一个结果,我们先不说为什么。接着讲我们的类加载器.
类的加载大致分为三个部分:加载,连接,初始化。
加载:查找并加载类的二进制数据
连接:1.验证(确保被加载类的准确性) 2.准备(为类的静态变量分配内存,并将其初始化为默认值) 3.解析(将类中的符号引用转化为直接引用)
初始化:为类的静态变量赋予正确的初始值(即赋上我们给出的值)
然后我们再看看java程序对类的使用方式:主动使用和被动使用。请注意下面我说的这句话
所有的JAVA虚拟机实现必须在每个类或接口被JAVA程序“首次主动使用”时才初始化他们。
那么什么叫主动使用?基本上分为6种情况:
--创建类的实例
--访问某个类或接口的静态变量,或者对该静态变量赋值
--调用类的静态方法
--反射
--初始化一个类的子类
--java虚拟机启动时被标明为启动类的类
了解了这些知识之后,我现在来回答之前的问题,
Singleton.getInstance(); 调用了类的静态方法,符合首次主动使用该类的情况!那么我们进入初始化阶段。
初始化已经属于类加载的第三步了,在第二步的连接的准备部分,已经赋过一次默认值了。所以应该是这样一个过程:
1.singleton = null;count1=0;count2=0
2.singleton = new Singleton(); 此时执行构造函数,结果为count1=1;count2=1
3.count1没有被我们赋值跳过初始化,count2赋值为0所以结果为count1=1;count2=0
(*注意) 类的静态变量赋值的顺序是按照代码的书写的顺序执行的。
修改代码如下:
package com.tfdd.test; /**
* @desc 类加载校验
* @author chenqm
* @date 2016年2月2日
*/
class Singleton{
public static int count1 ;
public static int count2 = 0;
private static Singleton singleton = new Singleton(); private Singleton(){
count1++;
count2++;
} public static Singleton getInstance(){ return singleton;
} }
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.count1);
System.out.println(singleton.count2);
}
}
输出结果为
1
1
证明赋值的顺序是根据代码书写的先后顺序执行的!
JVM之类加载器上篇的更多相关文章
- JVM自定义类加载器加载指定classPath下的所有class及jar
一.JVM中的类加载器类型 从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器. 1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责 ...
- 【深入理解JVM】类加载器与双亲委派模型 (转)
出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...
- 1.1 jvm核心类加载器--jdk源码剖析
目录 前提: 运行环境 1. 类加载的过程 1.1 类加载器初始化的过程 1.2 类加载的过程 1.3 类的懒加载 2. jvm核心类加载器 3. 双亲委派机制 4. 自定义类加载器 5. tomca ...
- 【JVM】JVM之类加载器
一.前言 首先,小小测试,看是否已经掌握了JVM类加载的过程 1.1.测试一 class Singleton { private static Singleton sin = new Singleto ...
- JVM之类加载器下篇
除了自定义的类加载之外,jvm存在三种类加载器,并以一种父委托的加载机制进行加载. --启动类加载器,又称根加载器,是一个native的方法,使用c++实现.在java中我们用null标识,用于加载j ...
- 【深入理解JVM】类加载器与双亲委派模型
原文链接:http://blog.csdn.net/u011080472/article/details/51332866,http://www.cnblogs.com/lanxuezaipiao/p ...
- JVM学习一:JVM之类加载器概况
18年转眼就3月份都快结束了,也就是说一个季度就结束了:而我也因为年前笔记本坏了,今天刚修好了,那么也应该继续学习和博客之旅了.今年的博客之旅,从JVM开始学起,下面我们就言归正传,进入正题. 一.J ...
- (转)JVM——自定义类加载器
背景:为什么要自定义,如何自定义,实现过程 转载:http://blog.csdn.net/SEU_Calvin/article/details/52315125 0. 为什么需要自定义类加载器 网上 ...
- JVM虚拟机-类加载器子系统
转自博客:http://www.cnblogs.com/muffe/p/3541189.html 还有一些自己补充的知识点 一.类加载器基本概念 顾名思义,类加载器(class loader)用来 ...
随机推荐
- maven配置发布仓库
首先,在工程的pom.xml中添加仓库信息 <distributionManagement> <repository> <id>releases</id> ...
- 第二次作业:Github的使用
Github的使用 一·注册: 要想使用github第一步当然是注册github账号了.之后就可以创建仓库了(免费用户只能建公共仓库),Create a New Repository,填好名称 ...
- Entity Framework 5.0系列之EF概览
概述 在开发面向数据的软件时我们常常为了解决业务问题实体.关系和逻辑构建模型而费尽心机,ORM的产生为我们提供了一种优雅的解决方案.ADO.NET Entity Framework是.NET开发中一种 ...
- Linux sort命令
200 ? "200px" : this.width)!important;} --> 介绍 sort命令是一个文本排序命令,它能对标准输入和文本文件进行排序,并且能将结果通 ...
- Android多线程分析之三:Handler,Looper的实现
Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多 ...
- Linux创建用户(转)
这篇文章总结的太好了,让我没动力新写一篇了,啊哈哈哈哈. 源自:http://www.cnblogs.com/ylan2009/articles/2321177.html Linux 系统是一个多用户 ...
- java程序 启动时参数
iEMP34:/opt/version/lktest/b030/jre/jre_linux/bin # ./java -classpath . SysInfo Exception in threa ...
- MR原理
三.MapReduce运行原理 1.Map过程简述: 1)读取数据文件内容,对每一行内容解析成<k1,v1>键值对,每个键值对调用一次map函数 2)编写映射函数处理逻辑,将输入的< ...
- 使用JSExcelXML.js导出Excel模板
github地址:https://github.com/464884492/JSExcelXml 业务系统显示效果图 导出模板图 功能描述 世间万物总是相生相克,既然我们的客户要求有导出Ex ...
- WPF入门教程系列四——Dispatcher介绍
一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以 ...