java反射跨空间调用类_《深入Java虚拟机》学习笔记五:类型生命周期

Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码文件是一种平台无关的中间编译结果,字节码文件由java虚拟机读取,

第七章 类型的生命周期

1、 类型装载、链接与初始化      Java虚拟机通过装载、链接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用。其中,装载就是把二进制的Java类型读入Java虚拟机中,而连接就是把这种已经读入虚拟机的二进制形式的类型数据合并到虚拟机的运行状态中去。连接阶段分了三个步骤:验证、准备和解析。验证确保了Java类型数据格式的正确并且适于Java虚拟机使用,而准备步骤则负责为该类型分配它所需的内存,比如为它的类变量分配内存,“解析”步骤则负责把常量池中的符号引用转换为直接引用(也可以在运行中的程序真正使用某个符号引用时再去解析它)。初始化将给类变量赋予适当的初始值。装载、连接和初始化这三个阶段必须按顺序进行。

虚拟机严格定义了初始化的时机:

① 当创建某个类的新实例时(或者通过在字节码中执行new指令,或者通过不明确的创建、反射、克隆或者反序列化)。

② 当调用某个类的静态方法时(即在字节码中执行invokestatie指令时)。

③ 当使用某个类或接口的静态字段,或者对该字段赋值时(在字节码中,执行getstatic或者putstatic指令时),用final修饰的静态字段除外,它被初始化为一个编译时的常量表达式。

④ 当调用JavaAPI中某些反射方法时,比如类Class中的方法或者java.reflect包中类的方法。

⑤ 当初始化某个类的子类时(某个类初始化时,要求它的超类已经被初始化了)。

⑥ 当虚拟机启动时某个标明为启动类的类(即含main()方法的那个类。)

任何一个类的初始化都要求它的所有祖先类(而不是祖先接口)预先被初始化。而一个接口的初始化,并不要求它的祖先接口预先被初始化。

1) 装载阶段由三个基本动作组成:

① 通过该类型的完全限定名,产生一个代表该类型的二进制数据流。

② 解析这个二进制数据流为方法区内的内部数据结构。

③ 创建一个表示该类型的java.lang.Class类的实例。

如果一个类装载器在预先装载时遇到缺失或者错误的class文件,它必须等到程序首次主动使用该类时才报告错误,如果一个类一直没有被程序主动使用,那么该类装载器就不会报告错误。

2) 验证,类型被转载后,就准备进行连接了,连接过程的第一步是验证,确认类型符合Java语言的语义,并且他不会危及虚拟机的完整性。

3) 准备阶段,Java虚拟机为类变量分配内存,设置默认初始值,虚拟机把给类变量新分配的内存根据类型设置为默认值。准备阶段,Java虚拟机实现可能也为一些数据结构分配内存,目的是提高运行程序的性能。

4) 解析过程就是在类型的常量池中寻找类、接口、字段和方法的符号引用,把这些符号引用换成直接引用的过程。

5) 初始化就是为类变量赋予正确的初始值,“正确”初始值指的是程序员希望这个类变量所具备的起始值,正确的初始值是和在准备阶段赋予的默认初始值对比而言的。

初始化一个类包含两个步骤:

① 如果类存在直接超类的话,且直接超类还没有被初始化,就先初始化直接超类。

② 如果类存在一个类初始化方法,就执行此方法。

当初始化一个超类时,也需要包含这两个步骤,因此第一个被初始化的类用远视Object,然后是被主动使用的类的继承树上所有的类,超类总是在子类之前被初始化。初始化接口并不需要初始化它的父接口,因此初始化一个接口只需要一步,如果接口初始化方法的话,就执行此方法。

()方法的代码并不显式地调用超类的()方法,在Java虚拟机调用类的()方法之前,它必须确认超类()方法已经被执行了。

Java虚拟机必须确保初始化过程被正确地同步,如果多个线程需要初始化一个类,仅仅允许一个线程初始化,其他线程需要等待,当活动的线程完成了初始化过程后,他必须通知其他等待的线程。

Java编译器把类变量初始化语句和静态初始化语句的代码都放到class文件的 ()方法中,顺序就按照它们在类或者接口声明中出现的顺序。并非所有的类都需要在它们的class文件中拥有一个()方法。如果类声明了类变量,但是没有明确使用类变量初始化语句或者静态初始化语句初始化它们,那么类不会有 ()方法。如果累仅仅包含静态final变量的类变量初始化语句,而且这些类变量初始化语句采用编译时常量表达式,类也不会有()方法,只有那些的确需要执行Java代码来赋予类变量正确初始值的类才会有类初始化方法。

主动使用和被动使用:

2、 对象声明周期

一旦一个类被装载、连接和初始化,它就随时可以使用了。程序可以访问它的静态字段,调用它的静态方法,或者创建它的实例。

1) 类实例化:在Java程序中,类可以被明确或者隐含地实例化。实例化一个类有四种途径:明确地使用new操作符;调用Class或者java.lang.reflect.Constuctor对象的newInstance()方法,调用任何现有对象的clone();或者通用java.io.ObjectInputStream类的getObject()方法反序列化。

当Java虚拟机创建一个类的新实例时,不管是明确的还是隐含的,首先都需要在堆中为保存对象的实例变量分配内存,所有在对象的类中它的超类中声明的变量都要分配内存。

2) 垃圾收集和对象的终结

程序可以明确或者隐含地位对象分配内存,但是不能明确地释放内存。如果类声明了一个名为finalize()的返回void的方法,垃圾收集器会在释放这个实例所占据的内存空间之前执行这个方法(被称为终结方法)一次。垃圾收集器最多只会调用一个对象的终结方法一次(在对象变成不再被引用的之后的某个时候,在占据的对象被重用之前)。HotSpot JVM收集器               上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器。        如果两个收集器之间存在连线,就说明它们可以搭配使用。 Serial(串行GC)收集器 Serial收集器是一个 新生代收集器, 单线程执行,使用 复制算法

3、 卸载类型

在很多方面,Java虚拟机中类的生命周期和对象的生命周期很相似。类的垃圾收集和卸载之所以在java虚拟机中很重要,因为java程序可以在运行时通过用户自定义的类装载器装载类型来动态的扩展程序。所有被装载的类型都在方法区占据内存空间,如果Java程序持续通过用户自定义的类装载器装载类型,方法区的内存足迹就会不断增长,如果某些动态装载的类型只是临时需要,当它们不再被引用之后,占据的内存空间可以通过卸载类型而释放。

Java虚拟机通过何种方法来确定一个动态装载类型是否仍然需要被程序需要呢?其判断方式与判断对象是否仍然被程序需要的方式很类似。如果程序不再引用某类型,那么这个类型就无法再对未来的计算过程产生影响。类型变成不可触及的,而且可以被垃圾收集。

使用启动类装载器装载的类型永远是可触及的,所以永远不会被卸载,只有使用用户自定义类装载器装载的类型才会变成不可触及的。

判断动态装载的类型Class实例在正常的垃圾收集过程中是否可以触及有两种方式,第一,也是最明显的,如果程序保持对Class实例的明确引用,它就是可触及的。其次,如果在堆中还存在一个触及的对象,在方法区中它的类型数据指向一个Class实例,那么这个Class实例就是可触及的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值