通过Singleton单例模式,理解Java的类加载
---------------------------------------------------------------------
public class Singleton {
private static Singleton obj = new Singleton(); //1
public static int counter1; //2
public static int counter2 = 0; //3
public static Singleton getInstance() { //4
return obj; //5
}
private Singleton() { //6
counter1++; //7
counter2++; //8
}
public static void main(String[] args) { //9
Singleton obj = Singleton.getInstance(); //10
System.out.println("obj.counter1==" + obj.counter1); //11
System.out.println("obj.counter2==" + obj.counter2); //12
}
}
运行结果的确让人大跌眼镜,竟然是:
obj.counter1==1
obj.counter2==0
---------------------------------------------------------------------
之后使用eclipse代码跟踪了一下,发现竟然是程序竟然是这么执行的!
步骤以及说明如下:
1.根据Java的类加载机制,加载类时首先分配static变量默认值以及执行static块,具体顺序根据代码中的顺序来执行.即:程序执行到1步骤,先分配obj=null,然后调用 Singleton()方法;
2.调用Singleton()方法,进入Singleton()方法体,执行7和8步骤,将counter1和 counter2分别+1;
3.从Singleton()方法中返回,由于没有执行完所有的static的变量或者代码块的初始化,则继续从2步骤开始执行;
4.由于2步骤不进行初始化赋值,则counter1的值没有发生改变,还是==1;
5.执行3步骤,由于counter2 需要进行初始化,则执行counter2=0的代码,这个是问题的根源;
5.整个static执行完毕后,在进入10步骤,将结果打印出来为"counter1==1,counter2==0"
---------------------------------------------------------------------
总结:
1.由于单例模式比较特别,static的执行步骤跟代码的顺序有关.如果把private static Singleton obj = new Singleton();放到public static int counter1; public static int counter2 = 0;之后,则最终结果是"counter1==1,counter2==1".即:static的初始化跟代码顺序有关.
2. 类的实例构造函数其实是经过new操作后,JVM在分配实例的空间后,进行自动调用的方法.一般我们用来初始化实例的成员数据(这也是最常见的用法).
---------------------------------------------------------------------
说明自己对类的加载的认识:
1.第一次加载类时,JVM会给类的static变量分配空间,并且使用默认值初始化分配的空间(基本数据为0,对象为 null).笼统的说,就是把一些为0的空间分配给类的static变量.
2.根据类中的代码顺序,以此执行static变量的自定义初始化或者 static代码块.其中,我们可以在代码中给static变量赋值,也可以在static代码块中执行更加复杂的操作.
3.通过调用new操作符,向JVM申请类的实例变量的空间,即为类的实例分配非static变量的空间,同static变量分配空间一样,JVM也是使用默认值来初始化分配的非static变量的空间.这时,实例拥有一些为0的空间.
4.然后JVM调用类的构造函数,进行一系列的操作.一般我们都是做一些对非 static变量的初始化工作.从另外一个角度说,类的构造函数的作用跟类的static代码块差不多:构造函数会在非static变量获得空间后调用, 而static代码块会在static变量获得空间后调用.
5.需要注意的是,static代码块或者构造函数都是在类或者类实例拥有自己的内存空间后的前提下才被调用的,一般都用来自定义的初始化操作.
---------------------------------------------------------------------
对于上面的Singleton单例模式,比较特殊.主要是这几点:
1.在执行static变量的自定义初始化或者static代码块的时候,突然 new一个本身类的实例.
2.在构造函数中,对static变量进行赋值操作.
3.在返回时,继续执行未完成的static变量的自定义初始化或者static代码块工作,导致又重复对static变量重复赋值的操作.
---------------------------------------------------------------------
理解了上面几点,我想应该对JVM的类加载应该有一个比较明确的认识了:-)
发表评论
-
网络游戏同步的原理
2011-09-22 20:01 817不知道大家是否碰到过这种情况,当某个玩家发出一个火球,这个火球 ... -
java中的io系统详解
2010-09-16 23:21 885Java 流在处理上分为字符流和字节流。字符流处理的单元为 ... -
java中的日期处理类总结
2010-08-08 20:35 857java中的日期处理类总结:Date/Calendar/Gre ... -
体验J2SE 1.5新特性之增强For循环
2010-04-08 14:49 824J2SE 1.5提供了另一种形 ... -
XPath
2010-03-22 17:52 1621XPath 简介 XPath 是一门 ... -
全面总结Java泛型
2009-10-25 12:19 761虽然Scala创始人Martin Odersky说当年正是因为 ... -
理解java String
2009-10-20 15:07 612要理解 java中String的运 ... -
字符串相关
2009-10-20 15:06 588Java代码 public class St ... -
Java中"equals"和"=="的区别
2009-10-20 14:01 658一句话概括:==比较的 ... -
Java代码编写的30条建议
2009-05-14 22:21 745(1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母 ... -
深入了解Java泛型(三) -- 泛型方法
2009-05-07 09:51 1844前面提到的都是与类的泛型化相关的话题,不过方法也可以从泛型中受 ... -
深入了解Java泛型(二) -- 泛型列表与数组
2009-05-07 09:48 1020记得以前面试的时候曾 ... -
深入了解Java泛型(一) -- 泛型与原生态类型
2009-05-07 09:45 1221Java1.5引入了泛型之后, ... -
正则表达式入门
2009-05-07 09:16 611元字符: /b 代表着单词 ...
相关推荐
Java中的Singleton(单例模式)是一种常用的软件设计模式,它保证了类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象的场景中特别有用,因为它可以节省系统资源,例如数据库连接或者线程池...
Java中的单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供全局访问点。在Java编程中,单例模式常用于控制资源的访问,比如数据库连接池、线程池或者日志对象等。本篇文章将深入探讨如何在Java中...
单例模式是软件设计模式中的一种经典模式,用于确保一个类只有一个实例,并提供一个全局访问点。...通过学习和实践这些单例模式的实现,我们可以更好地理解和应用设计模式,提升代码的质量和可维护性。
单例模式的核心在于限制类的实例化,通常通过私有化构造函数和静态工厂方法来实现。当类的实例第一次被请求时,会创建一个对象并将其存储在一个静态变量中,后续的请求都会返回这个已经创建的对象,而不是创建新的...
单例模式是软件设计模式中的一种经典模式,它在Java编程中被广泛使用。这个模式的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处在于控制资源的共享,减少系统开销,以及在多线程环境中避免...
这样可以防止其他类通过常规方式创建实例,确保单例的唯一性。 在Android中,Singleton模式的应用场景包括但不限于: 1. 应用程序配置管理:例如,一个AppConfig类用于存储和管理应用的全局配置信息。 2. 数据库...
单例模式是软件设计模式中的一种基础模式,它在Java编程中被广泛使用。这个模式的主要目的是限制类的实例化,确保在整个程序运行过程中,该类只有一个实例存在。这样可以节省系统资源,尤其是在全局范围内只需要一个...
这是最简单的单例模式实现方式,它在类加载时就完成了初始化,所以是线程安全的。代码如下: ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton...
单例模式是软件设计模式中的一种经典模式,它在许多场景下被广泛使用...理解并熟练掌握单例模式的实现方式及其适用场景,对于编写高效、可维护的代码具有重要意义。在编程实践中,应根据项目需求选择最适合的实现策略。
单例模式(Singleton Pattern)是一种常用的软件设计模式,在系统中确保某个类只有一个实例,并提供一个全局访问点。这种模式通常用于控制资源的消耗,比如数据库连接、线程池等,以及确保某个系统配置的一致性。 #...
Singleton 单例模式是软件设计模式中的一种,它限制了类的实例化过程,确保一个类在整个系统中只有一个实例存在。这种模式常用于系统资源管理,比如数据库连接、线程池或者缓存服务等,因为这些资源往往需要全局共享...
Java单例模式是一种设计模式,它允许在程序中创建唯一一个类实例,通常用于管理共享资源,例如数据库连接、线程池或者配置对象等。单例模式的核心在于限制类的构造函数,确保类只能被初始化一次,从而实现全局唯一的...
在Java编程中,单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象的场景中尤其有用,因为它可以节省系统资源并确保对象间的协调一致。以下是...
单例模式是软件设计模式中的一种,它的核心思想是确保一个类在整个系统中只有一个实例,并提供一个全局访问点。在Java或类似编程语言中,单例模式常常被用来管理资源,比如数据库连接、线程池或者配置信息,因为这些...
单例模式(Singleton Pattern)作为一种最基本的创建型设计模式,其主要目的是控制一个类的实例化过程,确保在整个应用程序中仅存在一个实例,并且该实例能够被全局访问。这种模式在实际软件开发中有着极其广泛的应用...
Java中的单例模式是一种设计模式,它用于保证一个类只有一个实例,并提供一个全局访问点。这种模式在系统中需要控制实例数量,特别是当这个实例需要频繁地被多个对象共享时非常有用,例如数据库连接池、线程池或者...
单例模式是软件设计模式中的一种基础且广泛应用的模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种方法,每种都有其特定的优缺点和适用场景。以下是几种常见的单例...
单例模式是软件设计模式中的一种,用于控制类的实例化过程,确保一个类在整个程序运行期间只有一个实例存在。在Java中实现单例模式有多种方法,每种都有其特定的优缺点。以下是对单例模式及其Java实现的详细解释。 ...
### 单例模式 Singleton Pattern #### 概述 单例模式是一种常见的设计模式,属于创建型模式之一。这种模式的核心在于确保某个类只有一个实例存在,并且提供一个全局访问点来获取该实例。单例模式在Java开发中尤其...