zoukankan      html  css  js  c++  java
  • 类的加载、连接和初始化

    一.JVM和类

    package JVM;
    
    public class A {
            //定义该类的类变量
            public static int a = 6;                                        
    }
    package JVM;
    
    public class ATest {
        public static void main(String[] args) {
            //创建A的实例
            A a = new A();
            //让a的实例变量a自增
            a.a ++;
            System.out.println(a.a);
        }
    }

    package JVM;
    
    public class BTest {
        public static void main(String[] args) {
            //创建A的实例
            A b = new A();
            //输出b实例的变量a的值
            System.out.println(b.a);
        }
    }

     

    以上程序引出以下认识:

    /**
    *一.同一个JVM的所有线程,所有变量都处在同一个进程里
    * 它们都使用该JVM进程的内存区
    *二.JVM进程终止情况
    * 程序运行到最后正常结束
    * 程序运行使用System.exit()或Runtime.getRuntime().exit()代码处结束程序
    * 程序执行过程中遇到未捕捉的异常或错误而结束
    * 程序所在平台强制结束了JVM进程
    *三.这三个代码ATest和BTest是在两个不同的JVM进程中运行,所以ATest类修改会消失
    * 说明了JVM进程结束,该进程在内存中的状态将会丢失
    */


    二.类的加载

    1.系统还未被加载到内存中、则系统会通过加载、连接、初始化三个步骤来对该类进行初始化

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

    3.JVM提供类加载器(程序运行的基础)-->完成类加载

    4.类加载器的种类

    •   从本地文件系统加载class文件(绝大部分程序的类加载方式)
    •   从JAR加载class文件
    •  通过网路加载class文件
    •  把一个java源文件动态编译,并执行加载

    java虚拟机允许系统预先加载某些类


    三.类的连接

    类加载后,系统为止生成一个对应的class文件-->进入连接阶段

    类的连接:类的二进制数据合并到JRE中,类连接的三个阶段

    • 验证结构:被加载类内部结构是否正确
    • 分配内存:为类的类变量分配内存,并设置默认初始值
    • 解析符号:将类的二进制数据中的符号引用替换成直接引用

    四.类的初始化

    类的初始化:虚拟机负责对类进行初始化,主要就是对类变量进行初始化

    类变量指定初始化值有两种方式:

    • 声明类变量指定初始值
    • 使用静态初始化块为类变量指定初始化值
    package JVM;
    
    public class Test {
        //声明变量a时指定初始值
        static int a = 5;
        static int b;
        static int c;
        
        {
            //使用静态初始化块为变量b指定初始值
            b=6;
        }
    }

    JVM初始化一个类包含如下几个步骤:

    • 类还未被加载和连接
    • 类的直接父类还没有被初始化,则先初始化其直接父类
    • 假如类中有初始化语句,则系统依次执行这些初始化语句

    当执行第二个步骤时,系统对直接父类的初始化步骤也遵循此步骤1~3


    五.类初始化的时机

    ①创建类的实例

    ②调用某个类的类方法

    访问某个类或接口的类变量,或为该类变量赋值

    ④使用反射方式来强制创建某个类或接口对应的java.lang.class对象.例如代码:Class.forName("Person"),这行代码初始化还未初始化的类

    ⑤初始化某个类的子类

    ⑥直接用java.exe命令来运行某个主类

    ⑦特别情形:final型的类变量,如果该类变量的值在编译时就可以确定下来,该类变量相当于"宏变量".java编译器会在编译时直接把这个类变量出现的地方替换成它的值,因此即使程序使用该静态变量,也不会导致该类的初始化

    package JVM;
    
    class MyTest{    
        static 
        {
            System.out.println("静态初始化块....");
        }
        //使用一个字符串直接量为static final的类变量赋值
        static final String  compileConstant = "疯狂java讲义";
    }
    public class CompileConstantTest {
        public static void main(String[] args) {
            //访问、输出MyTest中的compileConstant类变量
            System.out.println(MyTest.compileConstant);  //①
        }
    }
    ①处代码当做"宏变量"处理,不会初始化

  • 相关阅读:
    自定义Collection类
    基本排序算法(冒泡排序,选择排序,插入排序)
    泛型
    XSD的学习
    SSH整合配置
    一个可以随时插入的json的简单实现
    将Properties文件的键值对调换位置重新生成一个文件
    JAVA MD5加密
    框架中退出登录
    java 生成 xml
  • 原文地址:https://www.cnblogs.com/zjm1999/p/10298485.html
Copyright © 2011-2022 走看看