Java类的静态块の二

在上一篇Java类的静态块の一中介绍到:类的静态块在类加载时候执行,执行早于构造函数,并且只执行一次。

但是在下面的例子中却发现JVM并不是把把所有的static模块都执行完成再执行其他(Java果然是解释性语言):

 1 /**
 2  * 单例模式 之 饿汉模式
 3  *
 4  * @author Administrator
 5  *
 6  */
 7 public class SingletonStarving {
 8     static {
 9         System.out.println("this is Starving Singleton3");
10     }
11
12     /*
13      * 1.将构造方法私有化,不能从外部直接创建对象
14      */
15     private SingletonStarving() {
16         System.out.println("this is Starving Singleton2");
17     }
18
19     static {
20         System.out.println("this is Starving Singleton5");
21     }
22
23     /*
24      * 2.声明类的唯一实例,使用private static修饰
25      */
26     private static SingletonStarving instance= new SingletonStarving();
27
28     static {
29         System.out.println("this is Starving Singleton4");
30     }
31
32     /*
33      * 3.提供一个用于获取实例的方法,使用public static修饰
34      */
35     public static SingletonStarving getInstance() {
36         return instance;
37     }
38
39     public void print() {
40         System.out.println("this is Starving Singleton");
41     }
42
43     public static void main(String[] args) {
44         for (int i = 0; i < 2; i++) {
45             SingletonStarving.getInstance().print();
46         }
47     }
48 }

输出结果:

this is Starving Singleton3
this is Starving Singleton5
this is Starving Singleton2
this is Starving Singleton4
this is Starving Singleton
this is Starving Singleton

解析:

首先程序从main方法进入,执行到第一次循环的45行,开始加载类,也就意味着开始执行static模块,然后先后输出第9和20行的打印输出方法,输出3和5,解释到26行的时候因为类已经加载一次了,所以就不会执行加载类,而是执行构造函数,所以输出2,继续往下走,继续执行第三个static模块,输出4,然后到现在 类加载完成,执行第一个getInstance()返回实例,再执行print(),然后循环体再往下再次执行45行,static模块只会执行一次(不会重复打印2,3,4),单例模式也不会再执行构造函数(不会打印2),所以第二次运行到45行的时候只会执行print()。

时间: 2024-10-08 01:05:59

Java类的静态块の二的相关文章

Java类的静态块の一

类的静态块在类加载时候执行,执行早于构造函数,并且只执行一次. 下面这个例子可以帮助理解: 1 package untility; 2 3 public class A { 4 // 静态块 5 static { 6 A c ; 7 System.out.println(200); 8 c = new A(); 9 i = 10; 10 } 11 12 public static int i; 13 public int j; 14 15 public A() { 16 System.out.p

Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序

Java 类的实例变量初始化的过程 静态块.非静态块.构造函数的加载顺序 先看一道Java面试题: 1 public class Baset { 2 private String baseName = "base"; 3 // 构造方法 4 public Baset() { 5 callName(); 6 } 7 // 成员方法 8 public void callName() { 9 // TODO Auto-generated method stub 10 System.out.p

别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.ClassLoader源码分析 11.自定义类加载器 12.加载类的三种方式 13.总结 14.特别注意 @ 前言 你是否真的理解java的类加载机制?点进文章的盆友不如先来做一道非常常见的面试题,如果你能做出来,可能你早已掌握并理解了java的类加载机制,若结果出乎你的意料,那就很有必要来了解了解j

Java类静态属性、静态块、非静态属性、非静态块、构造函数在初始化时的执行顺序

前言 今天在看Android ContentProvider实现的时候,突然想到了Java类在new的过程中,静态域.静态块.非静态域.非静态块.构造函数的执行顺序问题.其实这是一个很经典的问题,非常考察对Java基础知识的掌握程度.很多面试过程中相信也有这样的问题,趁着周末有时间复习一下. 结论 这里先把整理好的结论抛给大家,然后我在写个程序来验证我们的结论.在Java类被new的过程中,执行顺序如下: 实现自身的静态属性和静态代码块.(根据代码出现的顺序决定谁先执行) 实现自身的非静态属性和

JAVA学习第二十二课(多线程(二))- (多线程的创建方式一 :继承Thread类)

线程是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 创建新执行线程有两种方法. 一种方法是将类声明为 Thread 的子类.该子类应重写Thread 类的run 方法.另一种方法是声明实现 Runnable 接口的类.该类然后实现run 方法. 创建线程方式一:继承Thread类 一.创建线程的步骤: 1.定义一个类继承Thread类 2.覆盖Thread中的run()方法 3.直接创建Thread类子类的对象 4.调用start方法开启线程,并调用线程的任务run方法

跟王老师学反射(二):Java类的加载、连接和初始化

跟王老师学反射(二):Java类的加载.连接和初始化 主讲教师:王少华   QQ群号:483773664 学习内容: 了解类的加载.连接和初始化 一.类的生命周期 当我们编写一个java的源文件后,经过编译会生成一个后缀名为class的文件,这种文件叫做字节码文件,只有这种字节码文件才能够在java虚拟机中运行,java类的生命周期就是指一个class文件从加载到卸载的全过程.一个java类的完整的生命周期会经历加载.连接.初始化.使用.和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直

Java多线程基础(二)定时器类:Timer类和TimerTask类

Java多线程基础(二)定时器类:Timer类和TimerTask类 Timer类和TimerTask类是jdk实现定时器功能的早期方法,jdk1.5以前就支持Timer类和TimerTask类.JDK1.5之后引入了新的机制,将在后续博文中研究. 1 指定时间间隔后执行任务 import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TraditionalTimerTest {

Java 反射理解(二)-- 动态加载类

Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类 演示 我们以具体的代码来演示什么是动态加载类和静态加载类: 新建:Office.java: class Office { public static void main(String[] args) { // new 创建对象,是静态加载类,在编译时刻就需

Java反射基础(二)— Class类

上一篇博客中我们提到了ClassLoader,知道ClassLoader是用来动态加载某个Class文件到内存当中,但是这个Class文件是怎么生成的呢?从何而来?这又涉及到另一个概念-java.lang.Class. Class 是java的一个特殊类,对于我们定义的类.接口,它更算是一个抽象类.Class类用于封装被装入到JVM中的类(包括类和接口)的信息. 当一个类和接口被装入JVM时,就自动创建一个Class类的实例来表示这个类,也就是我们说的Class对象,收集了当前这个对象的基本信息