云迈博客

您现在的位置是:首页 > 后端开发 > Java > 正文

Java

深刻理解java类的加载以及ClassLoader源码分析

鹏程万里2020-10-08Java285
你是否真的理解java的类加载机制?点进文章的盆友不如先来做一道非常常见的面试题,如果你能做出来,可能你早已掌握并理解了java的类加载机制,若结果出乎你的意料,那就很有必要来了解了解java的类加载

你是否真的理解java的类加载机制?点进文章的盆友不如先来做一道非常常见的面试题,如果你能做出来,可能你早已掌握并理解了java的类加载机制,若结果出乎你的意料,那就很有必要来了解了解java的类加载机制了。代码如下
package com.jvm.classloader;

class Father2{
public static String strFather=”HelloJVM_Father”;

static{
    System.out.println("Father静态代码块");
}

}

class Son2 extends Father2{
public static String strSon=”HelloJVM_Son”;

static{
    System.out.println("Son静态代码块");
}

}

public class InitativeUseTest2 {
public static void main(String[] args) {

   System.out.println(Son2.strSon);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
运行结果:
Father静态代码块
Son静态代码块
HelloJVM_Son
1
2
3
4
嗯哼?其实上面程序并不是关键,可能真的难不倒各位,不妨做下面一道面试题可好?如果下面这道面试题都做对了,那没错了,这篇文章你就不用看了,真的。

package com.jvm.classloader;

class YeYe{
static {
System.out.println(“YeYe静态代码块”);
}
}

class Father extends YeYe{
public static String strFather=”HelloJVM_Father”;

static{
    System.out.println("Father静态代码块");
}

}

class Son extends Father{
public static String strSon=”HelloJVM_Son”;

static{
    System.out.println("Son静态代码块");
}

}

public class InitiativeUse {
public static void main(String[] args) {
System.out.println(Son.strFather);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
各位先用“毕生所学”来猜想一下运行的结果是啥…

注意了…
注意了…
注意了…

运行结果:
YeYe静态代码块
Father静态代码块
HelloJVM_Father
1
2
3
4
是对是错已经有个数了吧,我就不拆穿各位的小心思了…

以上的面试题其实就是典型的java类的加载问题,如果你对Java加载机制不理解,那么你可能就错了上面两道题目的。这篇文章将通过对Java类加载机制的讲解,让各位熟练理解java类的加载机制。

其实博主还是想在给出一道题,毕竟各位都已经有了前面两道题的基础了,那么请看代码:

package com.jvm.classloader;

class YeYe{
static {
System.out.println(“YeYe静态代码块”);
}
}

class Father extends YeYe{
public final static String strFather=”HelloJVM_Father”;

static{
    System.out.println("Father静态代码块");
}

}

class Son extends Father{
public static String strSon=”HelloJVM_Son”;

static{
    System.out.println("Son静态代码块");
}

}

public class InitiativeUse {
public static void main(String[] args) {
System.out.println(Son.strFather);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
注意了
注意了
注意了

运行结果:HelloJVM_Father
1
冲动的小白童鞋看到了运行结果,果断的注销了博客账户…

1、什么是类的加载(类初始化)
JVM重要的一个领域:类加载

当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。

而类加载必然涉及类加载器,下面我们先来了解一下类的加载。

类的加载(类初始化):

1、在java代码中,类型的加载、连接、与初始化过程都是在程序运行期间完成的(类从磁盘加载到内存中经历的三个阶段)【牢牢记在心里】

2、提供了更大的灵活性,增加了更多的可能性
虽然上面的第一句话非常简短,但是蕴含的知识量却是巨大的!包含两个重要的概念:

1、类型

定义的类、接口或者枚举称为类型而不涉及对象,在类加载的过程中,是一个创建对象之前的一些信息

2、程序运行期间

程序运行期间完成典型例子就是动态代理,其实很多语言都是在编译期就完成了加载,也正因为这个特性给Java程序提供了更大的灵活性,增加了更多的可能性

1、1.类加载注意事项
1、类加载器并不需要等到某个类被 “首次主动使用” 时再加载它关于首次主动使用这个重要概念下文将讲解
2、JVM规范允许类加载器在预料某个类将要被使用时就预先加载它
3、如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

首先给各位打个预防针:可能没有了解过JVM的童鞋可能看的很蒙,感觉全是理论的感觉,不勉强一字一句的“死看”,只要达到一种概念印象就好!等到有一定理解认识之后再回头看一遍就好很多了,毕竟学习是一种循进渐进的过程,记住没有捷径!

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~