首页编程java编程java加载器什么时候加载类,java中静态内部类什么时候加载

java加载器什么时候加载类,java中静态内部类什么时候加载

编程之家2023-10-11100次浏览

大家好,关于java加载器什么时候加载类很多朋友都还不太明白,今天小编就来为大家分享关于java中静态内部类什么时候加载的知识,希望对各位有所帮助!

java加载器什么时候加载类,java中静态内部类什么时候加载

Java中的类是什么时候被加载到虚拟机

这个问题java的比较核心的一个难题,我就针对问题做简要回答,不做深入讨论了:

1、编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型、格式检查与编译成字节码文件,而加载是指java*的过程,将.class文件加载到内存中去解释执行,即运行的时候才会有加载一说。

java加载器什么时候加载类,java中静态内部类什么时候加载

2、类的加载时机,肯定是在运行时,但并不是一次性全部加载,而是按需动态,依靠反射来实现动态加载,一般来说一个class只会被加载一次,之后就会从jvm的class实例的缓存中获取,谁用谁取就可以了,不会再去文件系统中加载.class文件了。

明白1,2点就够了,再深入要等一段才能明白了。

java加载器什么时候加载类,java中静态内部类什么时候加载

java中类加载器是怎么工作的

JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)

链接又分为三个步骤,验证、准备、解析

1)装载:查找并加载类的二进制数据;

2)链接:

验证:确保被加载类的正确性;

准备:为类的静态变量分配内存,并将其初始化为默认值;

解析:把类中的符号引用转换为直接引用;

3)初始化:为类的静态变量赋予正确的初始值;

那为什么我要有验证这一步骤呢?首先如果由编译器生成的class文件,它肯定是符合JVM字节码格式的,但是万一有高手自己写一个class文件,让JVM加载并运行,用于恶意用途,就不妙了,因此这个class文件要先过验证这一关,不符合的话不会让它继续执行的,也是为了安全考虑吧。

准备阶段和初始化阶段看似有点牟盾,其实是不牟盾的,如果类中有语句:private static int a= 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时

java中静态内部类什么时候加载

只有在加载内部类的时候才初始化

看懂以下的代码,那么对于类的加载,基本上就没问题了,最后类的加载过程的解释

public class Test6{

public static void main(String[] args){

new B();

new A.C();

}

}

class A{

private P p1= new P("A--p1");

static P p3= new P("A--p3");

public A(){

System.out.println("A()");

}

private P p2=new P("A--p2");

static{

new P("A--static");

}

{new P("A{...}");}

public static class C{

private P p1= new P("C--p1");

static P p3= new P("C--p3");

public C(){

System.out.println("C()");

}

private P p2=new P("C--p2");

static{

new P("C--static");

}

{new P("C{...}");}

}

}

class B extends A{

private P p1= new P("B--p1");

static P p3= new P("B-- p3");

public B(){

System.out.println("B()");

}

public P p2= new P("B-- p2");

static{

new P("B-- static");

}

{new P("B{...}");}

}

class P{

public P(String s){

System.out.println(s);

}

}

/*

有父类的情况

1.加载父类

1.1为静态属性分配存储空间并赋初始值

1.2执行静态初始化块和静态初始化语句(从上至下)

2.加载子类

2.1为静态属性分配存储空间

2.2执行静态初始化块和静态初始化语句(从上至下)

3.加载父类构造器

3.1为实例属性分配存数空间并赋初始值

3.2执行实例初始化块和实例初始化语句

3.3执行构造器内容

4.加载子类构造器

4.1为实例属性分配存数空间并赋初始值

4.2执行实例初始化块和实例初始化语句

4.3执行构造器内容

5回到main()

内部类的加载过程也一样

java的类加载后什么时候会被释放

java的类加载后且当使用阶段完成之后,java类就进入了卸载阶段,也就是所谓的释放。

使用阶段包括主动引用和被动引用,主动饮用会引起类的初始化,而被动引用不会引起类的初始化。

一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况,如图所示:

PS:关于类的卸载,在类使用完之后,如果满足下面的情况,类就会被卸载:

该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收。

该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

如果以上三个条件全部满足,jvm就会在方法区垃圾回收的时候对类进行卸载,类的卸载过程其实就是在方法区中清空类信息,java类的整个生命周期就结束了。

好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!

c java 类 区别是什么,javac与java的区别java中按位是什么意思啊 java中按位取反 ~5=-6为什么呀