初始化和类装载

由于 Java 中的一切东西都是对象,所以许多活动变得更加简单,这个问题便是其中的一例。Java中每个对象的代码都存在于独立的文件中。除非真的需要代码,否则那个文件是不会载入的。通常,我们可认为除非那个类的一个对象构造完毕,否则代码不会真的载入。装载的时候,所有static对象和 static代码块都会按照本来的顺序初始化(亦即它们在类定义代码里写入的顺序)。当然,static 数据只会初始化一次。

1.继承初始化

我们有必要对整个初始化过程有所认识,其中包括继承,对这个过程中发生的事情有一个整体性的概念。请

观察下述代码:

//: Beetle.java
// The full process of initialization.
class Insect 
{
  int i = 9;
  int j;
  Insect() {
  prt("i = " + i + ", j = " + j);
  j = 39;
  }
  static int x1 =
  prt("static Insect.x1 initialized");
  static int prt(String s) {
  System.out.println(s);
  return 47;
  }
}
public class Beetle extends Insect 
{
  int k = prt("Beetle.k initialized");
  Beetle() {
  prt("k = " + k);
  prt("j = " + j);
  }
  static int x2 =
  prt("static Beetle.x2 initialized");
  static int prt(String s) {
  System.out.println(s);
  return 63;
  }
  public static void main(String[] args) {
  prt("Beetle constructor");
  Beetle b = new Beetle();
  }
} 
该程序的输出如下:
static Insect.x initialized
static Beetle.x initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 63
j = 39

对Beetle 运行Java 时,发生的第一件事情是装载程序到外面找到那个类。在装载过程中,装载程序注意它有一个基础类(即extends 关键字要表达的意思),所以随之将其载入。无论是否准备生成那个基础类的一个对象,这个过程都会发生。若基础类含有另一个基础类,则另一个基础类随即也会载入,以此类推。接下来,会在根基础类(此时是Insect)执行 static 初始化,再在下一个衍生类执行,以此类推。保证这个顺序是非常关键的,因为衍生类的初始化可能要依赖于对基础类成员的正确初始化。此时,必要的类已全部装载完毕,所以能够创建对象。首先,这个对象中的所有基本数据类型都会设成它们的默认值,而将对象句柄设为null。随后会调用基础类构建器。在这种情况下,调用是自动进行的。但也完全可以用super 来自行指定构建器调用(就象在Beetle()构建器中的第一个操作一样)。基础类的构建采用与衍生类构建器完全相同的处理过程。基础顺构建器完成以后,实例变量会按本来的顺序得以初始化。最后,执行构建器剩余的主体部分。

从主程序main()开始执行,如果有extends则从最开始的父类开始向下执行,在类的初始化时先执行static语句,然后执行构造方法,如果是子类的话则先执行super()方法,最后加载其他程序。

时间: 2024-10-17 00:31:51

初始化和类装载的相关文章

Java中的类装载和初始化模块

在Java中,初始化模块是指用一对"{}"括起来的代码,可以与构造方法一起来对对象进行初始化.初始化模块又分为实例初始化模块和静态初始化模块(只能由类的静态成员引用,在类装载时进行调用) Java中,代码的执行顺序是: 1.装入类     1.1递归装入父类,直到继承链上的父类全部装入为止.     1.2类装入内存之后,静态数据域和静态初始块按照在类中出现的顺序进行执行. 2.调用类的构造方法     2.1递归调用父类的构造方法,直到父类为java.lang.Object为止.  

jvm类装载机制

1.Class.forName("org.whatisjava.reflect.Foo")首先会将reflection.Foo类装入JVM,并 返回与之关联的Class对象.JVM装入Foo类后对其进行初始化,调用了其static块中的代码. 2.类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性和适应性.. 一.简单过程 Java程序运

Java虚拟机类装载的原理及实现(转)

Java虚拟机类装载的原理及实现(转) 一.引言 Java虚拟机(JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中, 并使其成为JVM一部分的过程.JVM的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块, 而不影响系统其他功能模块的正常运行.本文将分析JVM中的类装载系统,探讨JVM中类装载的原理.实现以及应用. 二.Java虚拟机的类装载实现与应用 2.1 装载过程简介 所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的c

JVM的类装载子系统

在JAVA虚拟机中,负责查找并装载类型的那部分被称为类装载子系统. JAVA虚拟机有两种类装载器:启动类装载器和用户自定义类装载器.前者是JAVA虚拟机实现的一部分,后者则是Java程序的一部分.由不同的类装载器装载的类将被放在虚拟机内部的不同命名空间中. 类装载器子系统涉及Java虚拟机的其他几个组成部分,以及几个来自java.lang库的类.比如,用户自定义的类装载器是普通的Java对象,它的类必须派生自java.lang.ClassLoader类.ClassLoader中定义的方法为程序提

Java类装载过程

类装载过程由JVM类装载子系统负责,主要包括一下三个步骤: 1)装载:查找并装载类型的二进制数据到虚拟机中 1.通过某些途径,产生一个代表该类型的二进制数据流 2.解析二进制数据流为方法区的内部数据结构 3.在堆中创建一个表示该类型的Class实例(装载步骤的最终产品) 注意:Java虚拟机规范允许类装载器缓存Java类型的二进制表现形式,如果预装载出错,则要等待该类被主动使用时抛出LinkageError的子类的异常 2)连接: 1.验证 确保导入的类格式正确 检查final类不能有子类,fi

jvm的类加载器,类装载过程

混沌初开,在一片名为jvm的世界中,到处都是一片虚无,直到一个名为BootstrapClassLoader的巨人劈开了世界,据说它是由名叫C++的女神所造,它从一个叫做jre/lib的宝袋中拿出一把开天之斧ExtensionClassLoader,以及其他各种各样五颜六色的宝物,这些宝物撒落在混沌世界中,化作了山山水水.紧接着,巨人又使用ExtensionClassLoader这把巨斧劈开了一个叫做jre/lib/ext的巨峰,那里瞬间迸发出了五颜六色的彩芒,彩芒四溅而去,让这个灰色的世界不再那

苹果新的编程语言 Swift 语言进阶(十一)--实例的初始化与类的析构

一 .实例的初始化          实例的初始化是准备一个类.结构或枚举的实例以便使用的过程.初始化包括设置一个实例的每一个存储属性为一个初始值,以及执行任何其它新的实例能够使用之前需要的设置或初始化. 一个类.结构或枚举能定义一个初始化方法来设置它的特性,用来确保它的实例的所有属性都有有效的初始值. 通过调用类.结构或枚举提供的初始化方法来执行实例的初始化过程. 类的实例也能实现一个析构,用来在类的实例释放之前执行任何特定的清除过程来释放分配的专有资源. 1 . 初始化方法的定义 初始化方法

从头认识java-6.7 初始化与类的加载

这一章节我们来讨论一下初始化与类的加载. 简单的说,类是在static成员被访问的时候加载的. 我们下面举一个比较复杂的例子,然后解释一下加载和初始化的顺序. package com.ray.ch06; public class Sub extends Father { private int b = print("b");// 5 private static int c = print("c");// 1 public Sub() { System.out.pr

使用构造函数初始化三角形类

方法1:使用带参数构造函数,即Triangle(double x, double y, double z),三边长在调用时由实参直接给出 #include <iostream> #include <cmath> using namespace std; class Triangle { public: //带参构造函数 Triangle(double x, double y, double z); double perimeter(void);//计算三角形的周长 double a