关键词:
JAVA源码编译由三个过程组成:
1、源码编译机制。
2、类加载机制
3、类执行机制
我们这里主要介绍编译和类加载这两种机制。
一、源码编译
代码编译由JAVA源码编译器来完成。主要是将源码编译成字节码文件(class文件)。字节码文件格式主要分为两部分:常量池和方法字节码。
二、类加载
类的生命周期是从被加载到虚拟机内存中开始,到卸载出内存结束。过程共有七个阶段,其中到初始化之前的都是属于类加载的部分
加载----验证----准备----解析-----初始化----使用-----卸载
系统可能在第一次使用某个类时加载该类,也可能采用预加载机制来加载某个类,当运行某个java程序时,会启动一个java虚拟机进程,两次运行的java程序处于两个不同的JVM进程中,两个jvm之间并不会共享数据。
1、加载阶段
这个流程中的加载是类加载机制中的一个阶段,这两个概念不要混淆,这个阶段需要完成的事情有:
1)通过一个类的全限定名来获取定义此类的二进制字节流。
2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3)在java堆中生成一个代表这个类的Class对象,作为访问方法区中这些数据的入口。
由于第一点没有指明从哪里获取以及怎样获取类的二进制字节流,所以这一块区域留给我开发者很大的发挥空间。这个我在后面的类加载器中在进行介绍。
2、准备阶段
这个阶段正式为类变量(被static修饰的变量)分配内存并设置类变量初始值,这个内存分配是发生在方法区中。
1、注意这里并没有对实例变量进行内存分配,实例变量将会在对象实例化时随着对象一起分配在JAVA堆中。
2、这里设置的初始值,通常是指数据类型的零值。
private static int a = 3;
这个类变量a在准备阶段后的值是0,将3赋值给变量a是发生在初始化阶段。
3、初始化阶段
初始化是类加载机制的最后一步,这个时候才正真开始执行类中定义的JAVA程序代码。在前面准备阶段,类变量已经赋过一次系统要求的初始值,在初始化阶段最重要的事情就是对类变量进行初始化,关注的重点是父子类之间各类资源初始化的顺序。
java类中对类变量指定初始值有两种方式:1、声明类变量时指定初始值;2、使用静态初始化块为类变量指定初始值。
初始化的时机
1)创建类实例的时候,分别有:1、使用new关键字创建实例;2、通过反射创建实例;3、通过反序列化方式创建实例。
1
2
|
new Test(); Class.forName(“com.mengdd.Test”); |
2)调用某个类的类方法(静态方法)
1
|
Test.doSomething(); |
3)访问某个类或接口的类变量,或为该类变量赋值。
1
2
|
int b=Test.a; Test.a=b; |
4)初始化某个类的子类。当初始化子类的时候,该子类的所有父类都会被初始化。
5)直接使用java.exe命令来运行某个主类。
除了上面几种方式会自动初始化一个类,其他访问类的方式都称不会触发类的初始化,称为被动引用。
1、子类引用父类的静态变量,不会导致子类初始化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class SupClass
public static int a = 123 ; static
System.out.println( "supclass init" );
public class SubClass extends SupClass
static
System.out.println( "subclass init" );
public class Test
public static void main(String[] args)
System.out.println(SubClass.a);
|
执行结果:
supclass init
123
2、通过数组定义引用类,不会触发此类的初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class SupClass
public static int a = 123 ; static
System.out.println( "supclass init" );
public class Test
public static void main(String[] args)
SupClass[] spc = new SupClass[ 10 ];
|
执行结果:
3、引用常量时,不会触发该类的初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class ConstClass
public static final String A= "MIGU" ; static
System.out.println( "ConstCLass init" );
public class TestMain
public static void main(String[] args)
System.out.println(ConstClass.A);
|
执行结果:
MIGU
用final修饰某个类变量时,它的值在编译时就已经确定好放入常量池了,所以在访问该类变量时,等于直接从常量池中获取,并没有初始化该类。
初始化的步骤
1、如果该类还没有加载和连接,则程序先加载该类并连接。
2、如果该类的直接父类没有加载,则先初始化其直接父类。
3、如果类中有初始化语句,则系统依次执行这些初始化语句。
在第二个步骤中,如果直接父类又有直接父类,则系统会再次重复这三个步骤来初始化这个父类,依次类推,JVM最先初始化的总是java.lang.Object类。当程序主动使用任何一个类时,系统会保证该类以及所有的父类都会被初始化。
java类加载机制详解(代码片段)
引子Java虚拟机的启动是通过引导类加载器(BootstrapClassLoader)创建一个初始类 (InitialClass)来完成,这个类是由虚拟机的具体实现指定。紧接着,Java虚拟机链接这个初始类,初始化并调用它的publicvoidmain(String[])方法。之后的整个... 查看详情
jvm之java类加载机制和类加载器(classloader)的详解
当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。 &nb... 查看详情
jvm系列-jvm类加载机制详解(代码片段)
前言本文将由浅及深,介绍Java类加载的过程和原理,进一步对类加载器的进行源码分析,完成一个自定义的类加载器。正文(一).类加载器是什么类加载器简言之,就是用于把.class文件中的字节码信息转化为具体的java.lang.Class对... 查看详情
jvm类加载机制详解(代码片段)
如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。加载加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法... 查看详情
jvm类加载机制详解类加载器与双亲委派模型
...gs.com/panchanggui/p/9952524.html 在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有:1、通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件)。而获... 查看详情
jvm之java类加载机制和类加载器(classloader)的详解(代码片段)
当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。一、类加载... 查看详情
java类加载器详解(代码片段)
文章目录1.什么是类加载器?3.类加载器的执行过程2.类加载器的分类3.双亲委派机制4.boostrapclassLoader启动类加载器打印显示null5.小注意事项1.什么是类加载器?类加载器就是加载.class文件的,将其加载出对应的对象来... 查看详情
java类加载器和双亲委派机制
前言之前详细介绍了Java类的整个加载过程(类加载机制详解)。虽然,篇幅较长,但是也不要被内容吓到了,其实每个阶段都可以用一句话来概括。1)加载:查找并加载类的二进制字节流数据。2)验证:保证被加载的类的正确... 查看详情
反射详解
1.什么是反射?Java中的反射机制是Java语言的一个很重要的特性,是Java“动态性”的重要体现。Java反射机制让我们在程序运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用他... 查看详情
java面试--jvm类加载
...作用,能重复加载某个类吗(阿里面试题)一、JVM类加载机制详解JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化:加载加载过程主要完成三件事情:1、通过类的全限定名来获取定义此类的二进制字节流2、将这个类... 查看详情
jvm之java类加载机制和类加载器(classloader)的详解(代码片段)
手把手写代码:三小时急速入门springboot—企业级微博项目实战—>csdn学院当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,... 查看详情
jvm类加载器,类加载机制详解(代码片段)
前言今天我们来讲讲jvm里类加载的过程,我们写了那么多类,却不知道类的加载过程,岂不是很尴尬。jvm的启动是通过引导类加载器(bootstrapclassloader)创建一个初始类(initialclass)来完成的,这个... 查看详情
jvm类加载机制详解
如下图所示,JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。加载加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法... 查看详情
详解java对象实例化过程
1对象的实例化过程对象的实例化过程是分成两部分:类的加载初始化,对象的初始化要创建类的对象实例需要先加载并初始化该类,main方法所在的类需要先加载和初始化类初始化就是执行<clinit>方法,对象实例化是执行<i... 查看详情
java基础学习总结(196)——javaspringdubbo三种spi机制详解(代码片段)
前言SPI全称为ServiceProviderInterface,是一种服务发现机制。SPI的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容... 查看详情
java基础学习总结(196)——javaspringdubbo三种spi机制详解(代码片段)
前言SPI全称为ServiceProviderInterface,是一种服务发现机制。SPI的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容... 查看详情
java基础学习总结(196)——javaspringdubbo三种spi机制详解(代码片段)
前言SPI全称为ServiceProviderInterface,是一种服务发现机制。SPI的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容... 查看详情
java反射机制详解(代码片段)
对于一般的开发者,很少需要直接使用Java反射机制来完成功能开发,但是反射是很多框架譬如Spring,Mybatis实现的核心,反射虽小,能量却很大。本文主要介绍反射相关的概念以及API的使用,关于反射的应用将在下一篇文章中介... 查看详情