先来段代码,大家瞧瞧运行pritln的结果是什么?(认真想一想哦😯)

package com.java.baseknowledge.classload;

public class ClssTest {
    
    
    public static void main(String[] args) {
        Single sing=Single.getInstance();
        System.out.println(sing.i);
        System.out.println(sing.j);
    }

}

class Single{
    
    public static Single sing =new Single();
    public static int i;    
    public static int j =9;
    
    private Single () {
        i++;
        j++;
    }
    
    public static Single getInstance() {
        
        return sing;
    }
}

---开篇:

1.java virtual machine 与程序的生命周期

1.执行了system.exit()的方法
2.program正常执行结束
3.program 运行过程中遇到了error 和exception
4.由于操作系统错误导致的Java virtual machine 退出

2.关于类的加载,连接与初始化

1,加载(classload):查找并加载类的二进制数据(硬盘到内存)。--》将其放在运行时数据区的方法区内,并在堆内存创建一个创建一个java.lang.class对象。用来封装类在方法区的数据结构,提供了访问方法区内的数据结构的接口即反射;
2,连接:
    (1)验证:确保被加载的类的正确性。
    (2)准备:为类的静态变量分配内存,并将其初始化为默认值。----》初始化默认值是 0 null 之类的,并没有赋予我们所赋予的值
    (3)解析:将类中的符号引用转换为直接引用
3.初始化:为类的静态变量赋于正确的初始值。(这里的赋予正确初始值是用户所赋予的值

 类加载器详解 .java program 对类的主动使用方式,会导致类的初始化,其他方式都不会进行类的初始化。

1.创建类的实例---》 xx x=new xx();
2.访问某个类或者接口的静态变量,或者对静态变量赋值
3.调用类的静态方法
4,反射调用--》 class。forname();
5.初始化一个类的子类
6.java virtual machine start 标明为启动类的类
 classloader 源码:
  A class loader is an object that is responsible for loading classes. The * class <tt>ClassLoader</tt> is an abstract class. Given the <a * href="#name">binary name</a> of a class, a class loader should attempt to * locate or generate data that constitutes a definition for the class. A * typical strategy is to transform the name into a file name and then read a * "class file" of that name from a file system. * * <p> Every {@link Class <tt>Class</tt>} object contains a {@link * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined * it. *
Trnslation:
class loader 是一个负责加载类的一个对象,是一个抽象的类,类加载器应该尝试定位或生成构成类的定义的数据
一种典型的策略是将名称转换成文件名,然后从文件系统中读取该名称的“类文件”。

每一个class 对象都包含了一个getclassloader 的方法引用,用于定义它的classloader

然后我们看一看class 类中的getclassloader method define;

/**

     * Returns the class loader for the class.  Some implementations may use

     * null to represent the bootstrap class loader. This method will return

     * null in such implementations if this class was loaded by the bootstrap

     * class loader.

     *

     * <p> If a security manager is present, and the caller's class loader is

     * not null and the caller's class loader is not the same as or an ancestor of

     * the class loader for the class whose class loader is requested, then

     * this method calls the security manager's {@code checkPermission}

     * method with a {@code RuntimePermission("getClassLoader")}

     * permission to ensure it's ok to access the class loader for the class.

     *

     * <p>If this object

     * represents a primitive type or void, null is returned.

Translation:

  返回这个类的类加载器,一些实现类可能会返回空去代表类加载器是bootstrap 类加载器。
如果类是被bootstrap 类加载的,就会返回空。
  原始的数据类型的加载器都会返回空;

三种 classloader

1.根类加载器(bootstrap 使用c++编写,无法看到底层实现)
2.扩展类加载器
3.系统加载器

连接的过程:

验证:

  对类文件的检查,确保类文件遵循Java 类文件固定格式
  语义检查,死否遵循语法规范
  字节码验证
  二进制兼容验证
准备
  为类的静态变量赋于初始值,并不是我们赋予的值,
解析:
    符号引用转换为直接引用,即比如car类的 run() 方法的符号引用是由run 方法的全名和相关描述符组成,在解析是,Java 会把这个符号引用替换为一个指针,指针指向
方法内存位置,指针就是直接引用;

初始化过程:

为静态变量赋于我们所给予的值,代替类连接过程准备阶段赋予的初始值,没有则保持初始值
静态变量的声明语句与静态代码块都是类初始化的语句,只是谁前谁后的问题

如上面例子中的--

package com.java.baseknowledge.classload;

public class ClssTest {
    
    
    public static void main(String[] args) {
        Single sing=Single.getInstance();
        System.out.println(sing.i);
        System.out.println(sing.j);
    }

}

class Single{
    /**
  * =======连接阶段赋初始值======
  *      sing =null;
  *      i=0;
  *      j=0;
  *==========初始化阶段===========
  *    new singal ==》 i=1;j=10;
  *    i =1;
  *    j=9;
  **/  
public static Single sing =new Single(); public static int i; public static int j =9; private Single () { i++; j++; } public static Single getInstance() { return sing; } }

 

posted on 2018-09-29 00:07  iscys  阅读(129)  评论(0编辑  收藏  举报