类型的生命周期

来源:互联网 发布:济南网络广播电视台 编辑:程序博客网 时间:2024/05/22 05:19

Java 虚拟机通过装载,连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用。


装载,就是把二进制形式的Java类型读入Java虚拟机中,而连接就是把这种已经读入虚拟机的二进制形式的类型数据合并到虚拟机的运行时状态中去。


连接分为三个步骤-------验证,准备和解析。“验证”步骤确保了Java类型数据格式正确并且适于虚拟机使用,而“准备”步骤则负责为该类型分配它所需的内存。“解析”步骤则负责把常量池的符号引用转化为直接引用。虚拟机实现可以“推迟”解析这一步,它可以当运行中的程序真正使用某个符号引用时再去解析它。当验证,准备和(可选的)解析步骤完成时,该类型就为初始化做好了准备。在初始化期间,都将给类变量赋以适当的初始值。


所有的Java虚拟机实现必须在每个类或者接口首次主动使用时初始化。下面六种情形符合主动使用的要求。

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

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

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

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

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

6.当虚拟机启动时某个被标明为启动类的类(即含有类方法的那个类)。



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

在Java程序中,类可以被明确或者隐含地实例化。实例化一个类有四种途径:

1.明确地使用new操作符。

2.调用Class或者java.lang.reflect.Constructor对象的newInstance方法。

3.调用任何对象的clone()方法。

4.通过java.io.ObjectInputStream类的getObject()方法反序列化。



除了这四种在Java源代码中明确地实例化对象的方法之外,还有几种情况下对象会被隐含地实例化。


在任何Java程序中第一个隐含实例化对象可能是保存命令行参数的String对象,每一个命令行参数都会有一个String对象的引用,把它们组成一个String数组并作为一个参数传递到每个程序的main()方法中。


另外两种隐含实例化类的方法和类装载的过程有关。首先,对于Java虚拟机装载的每一个类型,它会暗中实例化一个Class对象来代表这个类型。其次,当Java虚拟机装载了在常量池中包含CONSTANT_String_info入口的类的时候,它会创建新的String对象的实例来表示这些常量字符串。把方法区中的CONSTANT_String_info入口转化成一个堆中的String实例的过程是常量池解析过程的一部分。


还有一条隐含创建对象的途径是通过执行包含字符串连接符的表达式产生对象。如果这样的字符串不是一个编译时常量,用于中间处理的String和StringBuffer对象会在计算表达式的过程中创建。



程序可以明确或者隐含为对象分配内存,但是不能明确的释放内存。但一个对象不再为程序所引用了,虚拟机必须回收(垃圾收集)那部分内存。


类型的生命周期与对象生命周期相似,虚拟机创建并初始化对象,使程序能使用对象,然后在对象变得不再被引用后可选地执行垃圾收集。同样,虚拟机装载,连接并初始化类,使程序能使用类,当程序不再引用它们地时候可选地卸载它们。




原创粉丝点击