java基础之初始化与清理

Java语言是面向对象语言,操作的都是对象(万物皆对象),而对象需要通过初始化才可以使用。首先学习一下类在Java虚拟机的调用过程

一、类加载器 

类编译后会产生相应的Class对象(存储在.class文件),JVM通过使用类加载器(Class Loader)来加载类的字节码文件(.class),类加载器实质上是一条类加载器链,一般的,我们只会用到一个原生的类加载器,它只加载Java API等可信类,通常只是在本地磁盘中加载,这些类一般就够我们使用了。如果我们需要从远程网络或数据库中下载.class字节码文件,那就需要我们来挂载额外的类加载器。

一般来说,类加载器是按照树形的层次结构组织的,每个加载器都有一个父类加载器。另外,每个类加载器都支持代理模式,即可以自己完成Java类的加载工作,也可以代理给其它类加载器。

类加载器的加载顺序有两种,一种是父类优先策略,一种是是自己优先策略,父类优先策略是比较一般的情况(如JDK),在这种策略下,类在加载某个Java类之前,会尝试代理给其父类加载器,只有当父类加载器找不到时,才尝试自己去加载。自己优先的策略与父类优先相反,它会首先尝试子经济加载,找不到的时候才要父类加载器去加载,这种在web容器(如tomcat)中比较常见。

不管使用什么样的类加载器,类,都是在第一次被用到时,动态加载到JVM的。这句话有两层含义:

  1. Java程序在运行时并不一定被完整加载,只有当发现该类还没有加载时,才去本地或远程查找类的.class文件并验证和加载;
  2. 当程序创建了第一个对类的静态成员的引用(如类的静态变量、静态方法、构造方法——构造方法也是静态的)时,才会加载该类。Java的这个特性叫做:动态加载

需要区分加载和初始化的区别,加载了一个类的.class文件,不以为着该Class对象被初始化,事实上,一个类的初始化包括3个步骤:

  • 加载(Loading),由类加载器执行,查找字节码,并创建一个Class对象(只是创建);
  • 链接(Linking),验证字节码,为静态域分配存储空间(只是分配,并不初始化该存储空间),解析该类创建所需要的对其它类的应用;
  • 初始化(Initialization),首先执行静态初始化块static{},初始化静态变量,执行静态方法(如构造方法)。

 

Java在加载了类之后,需要进行链接的步骤,链接简单地说,就是将已经加载的java二进制代码组合到JVM运行状态中去。它包括3个步骤:

  1. 验证(Verification),验证是保证二进制字节码在结构上的正确性,具体来说,工作包括检测类型正确性,接入属性正确性(public、private),检查final class 没有被继承,检查静态变量的正确性等。
  2. 准备(Preparation),准备阶段主要是创建静态域,分配空间,给这些域设默认值,需要注意的是两点:一个是在准备阶段不会执行任何代码,仅仅是设置默认值,二个是这些默认值是这样分配的,原生类型全部设为0,如:float:0f,int 0, long 0L, boolean:0(布尔类型也是0),其它引用类型为null。
  3. 解析(Resolution),解析的过程就是对类中的接口、类、方法、变量的符号引用进行解析并定位,解析成直接引用(符号引用就是编码是用字符串表示某个变量、接口的位置,直接引用就是根据符号引用翻译出来的地址),并保证这些类被正确的找到。解析的过程可能导致其它的类被加载。需要注意的是,根据不同的解析策略,这一步不一定是必须的,有些解析策略在解析时递归的把所有引用解析,这是early resolution,要求所有引用都必须存在;还有一种策略是late resolution,这也是Oracle 的JDK所采取的策略,即在类只是被引用了,还没有被真正用到时,并不进行解析,只有当真正用到了,才去加载和解析这个类。

二、构造器

对象通过构造器初始化后调用,构造器分为无参构造器、有参构造器; 无参构造器又叫默认构造器。构造器名称与类名称相同,例:

class Dog{

 Dog(){}

 Dog(String name){}

}

DOg类的默认构造器是Dog()方法,其中我还定义了一个有一个参数(参数名是name,参数类型是String)的构造器Dog(String) 方法。

值得一提的是,在新建类时,如果开发人员自定义了构造方法,系统将不再自动为这个类创建默认构造器;so,如果开发人员本身没有创建构造器,系统将会自动为其创建默认构造器。帮助开发人员通过构造器来初始化--->使用对象。

对象的使用必须经过:声明、定义、初始化,才可以使用。

三、成员初始化

四、数组初始化

明确数组:相同类型、用一个标识符名称封装到一起的一个对象序列或基本数据类型序列的   集合。

int [] a;

String [] a;

一般来说,习惯初始化声明/定义一起用——————   int [] a = {1,2,3,4};     ||       String []  b = new String[10];   

posted @ 2019-12-26 21:05  zhengfy  阅读(166)  评论(0)    收藏  举报