三 类初始化概述

——万丈高楼平地起

1、类加载、链接、初始化

1.1  类加载:将类的class文件读入内存,并为之创建一个java.lang.Class对象

1.2 类的连接:

    验证:验证阶段用于检验被加载的类是否有正确的内部结构,和其他类协调一致

    准备:类准备阶段为类的类变量分配内存,并设置默认初始值

    解析:将类的二进制数据中的符号引用替换成直接饮用

1.3 初始化:主要对类变量进行初始化

例:

public class Test {
    static{
        a=1;
    }
    public static int a=5;
    public static void main(String[] args) {
        System.out.println(Test.a);
    }
}

对上例代码解析:首先把Test.java文件编译成Test.class文件(编译用javac命令)。当运行(java命令)时,开始执行上面的步骤(首次使用该类或预加载该类)。

类加载:生成 Test.class文件读入内存,并生成对应的Class对象,Class对象可以通过Class<Test> c= Test.class 方式获取;

类连接:准备阶段为类变量分配内存,并赋初始值。即4字节空间给变量a使用,并且初始值a=0。(关于默认值可以查询api或找度娘;类似javaScript中声明的提前,即总会把public static int a=0 放入最前面,然后执行a=1;a=5;)

初始化:初始化顺序是从上往下的,即先执行a=1;然后执行a=5;所以输出结果Test.a=5

2、 类初始化时机:一个类什么时候会初始化

2.1 创建类实例。比如通过new 创建对象或通过反射创建对象(创建对象不仅类得到实例化,而且对象也会被实例化)。

2.2 调用某个类的静态方法 或 操作静态属性(static修饰的)。比如上例中在main方法中调用Test.a

2.3 使用反射创建某个类的Class帝乡,比如上例中:Class<Test> c= Test.class 或者 Class<Test> c = Class.forName("Test");此时对象并未初始化,只是类初始化。

2.4 某个类被初始化时,它的父类将先被初始化。

2.5 运行main(主类)方法时。

3、类加载来源:通过不同类加载器

3.1 从本地文件系统加载class文件。例如:平时用IDE(如eclipse)工具编写的程序,将自动编译成class文件,当点击运行时,便是加载的class文件。

3.2 从jar包加载class文件。例如:jdbc编程使用的数据库驱动类jar包,或使用spring框架编写程序,需要下载的很多jar包

3.3 通过网络加载class文件。

3.4 把一个java源程序动态编译,并执行加载。

4、JVM初始化一个类的几个步骤

4.1 假如这个类还没有加载和连接,则程序先加载并连接该类

4.2 假如假如该类的直接父类还没有被初始化,则先初始化其直接父类

4.3 假如了,类中有初始化语句,则系统依次执行这些初始化语句

当执行到3.2初始化父类时,重复3.1~3.3步骤,所以JVM最先初始化的总是java.lang.Object类。

5、java的程序结束

5.1 程序运行到最后正常结束

5.2 程序运行到使用System.exit() 或者 Runtime.getRuntime().exit()代码处

5.3 程序执行中遇到未捕获的异常或错误而结束

5.4 程序所在的平台强制结束了JVM进程。比如:打开任务管理器 ctrl+shift+esc(window7下),找到进程强制结束

时间:2016年1月13日09:56:05

备注:内容主要摘自与李刚老师的“疯狂java讲义”

时间: 2024-10-08 10:29:18

三 类初始化概述的相关文章

转!!关于java类初始化顺序

原文地址:http://www.cnblogs.com/luckygxf/p/4796955.html 1.没有继承 静态变量->静态初始化块->变量->变量初始化块->构造方法 2.有继承的情况 父类静态变量->父类静态初始化块->子类静态变量->子类静态变量初始化块->父类变量初始化->父类变量初始化块->父类构造方法->子类变量初始化->子类变量初始化块->子类构造方法 --------------------------

《初始化块:普通初始化块、静态初始化块(类初始化块)》

1 /* 2 初始化块:普通初始化块.静态初始化块(类初始化块) 3 4 下面程序创建了三个类:Root,Mid和Leaf, 5 者三个类都提供了静态初始化块和普通初始化块, 6 而且Mid类里还是用this调用重载构造区,而 7 Leaf使用super显示调用父类指定的构造器 8 */ 9 class Root 10 { 11 static{ 12 System.out.println("Root的静态初始化块"); 13 } 14 15 { 16 System.out.printl

c++ 类初始化

一. 成员初始化列表的位置. 成员初始化列表的位置位于构造函数的函数体和参数表之间.构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式,初始化式可以是表达式.派生类构造函数的形参还有其余常量. 通过成员初始化表,类数据成员可以被显式初始化.成员初始化表是由逗号分隔的成员/名字实参对.例如下面的双参数构造函数的实现就使用了成员初始化表. _name是string 型的成员类对象. Account::Account( const char*

Java类初始化顺序经典实例

一.阿里巴巴笔试题: 1 public class T implements Cloneable { 2 public static int k = 0; 3 public static T t1 = new T("t1"); 4 public static T t2 = new T("t2"); 5 public static int i = print("i"); 6 public static int n = 99; 7 8 public

类初始化和实例初始化

一.类初始化过程 一个类要创建实例需要先加载并初始化该类 main方法所在的类需要先加载和初始化 一个子类要初始化需要先初始化父类 一个类初始化就是执行< clinit>()方法 < clinit>()方法由静态类变量显示赋值代码和静态代码块组成 类变量显示赋值代码和静态代码块代码从上到下顺序执行 < clinit>()方法只执行一次 二.实例初始化过程 实例初始化就是执行()方法 < init>()方法可能重载有多个,有几个构造器就有几个方法 < i

[读书笔记] java类初始化

以下内容来自周志明的<深入理解java虚拟机>: 类初始化阶段是类加载过程的最后一步,前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制. 到了初始化阶段,才真正开始执行类中定义的Java程序代码(或者说是字节码). 在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者可以从另外一个角度来表达:初始化阶段是执行类构造器<clinit>()方法的过程.

Java基础知识强化之集合框架笔记58:Map集合之LinkedHashMap类的概述

1. LinkedHashMap类的概述 LinkedHashMap:Map接口的哈希表(保证唯一性) 和 链接(保证有序性)列表实现,具有可预知的迭代顺序. 2. 代码示例: 1 package cn.itcast_03; 2 3 import java.util.LinkedHashMap; 4 import java.util.Set; 5 6 /* 7 * LinkedHashMap:是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序. 8 * 由哈希表保证键的唯一性 9 * 由链

Android(java)学习笔记136:Java类初始化顺序

Java类中初试化的顺序: 由此得出Java普通类初始化顺序结论: 静态变量 静态初始化块 变量 初始化块 构造器 由此得出Java继承类初始化顺序结论: 1 .继承体系的所有静态成员初始化(先父类,后子类) 2 .父类初始化完成(普通成员的初始化-->构造函数的调用) 3 .子类初始化(普通成员-->构造函数) Java初始化顺序如图: 代码演示: class Sample { Sample(String s) { System.out.println(s); } Sample() { Sy

虚基类初始化问题

在包含有继承关系的类里,生成一个派生类对象,要调用构造函数进行初始化此对象,而构造函数的调用顺序是先调用最顶层基类的构造函数,次顶层....等:但在普通继承和虚继承里存在区别 普通继承:父类只能由其直接派生类初始化 1 class A 2 { 3 char a; 4 public: 5 A(char _a) :a(_a){ cout << a << endl; } 6 }; 7 8 class B:public A 9 { 10 char b; 11 public: 12 B(ch