* Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区的数据的接口。类是反射的入口。
有两种类型的类加载器:
# Java虚拟机自带的加载器
1、根类加载器(Bootstrap)
2、扩展类加载器(Extension)
3、系统(应用)类加载器(System)
1)用户自己定义的类加载器
2)java.lang.ClassLoader的子类
3)用户可以定制的加载方式
类的加载:
* 类的加载器并不需要等到某个类被“首次主动使用”时再加载它。
怎么理解这句话呢,我们就拿第一篇(JVM原理一:类加载器深入解析与阶段分解)文章的例子说明:
我们加上-XX:+TraceClassLoading 参数
public class MyTest {
public static void main(String[] args) {
System.out.println(MyChild.str);
}
}
class MyParent1{
public static String str = “hello world”;
static{
System.out.println(“MyParent1 static block”);
}
}
class MyChild extends MyParent1{
public static String str2 = “welcome”;
static{
System.out.println(“MyChild static bloack”);
}
}
运行结果:
虽然子类没有被初始化,但是通过日志可以看出子类已经被加载了。
* JVM规范允许类加载器在预料将要被使用时就预先加载它,如果在预先加载的过程中遇到.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkError错误)
* 如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。
类的验证:
- 类的验证的内容
- 类文件的结构检查
- 语义检查
- 字节码检查
- 二进制兼容性的验证
类的准备:
类的初始化:
类的初始化步骤:
- 假如这个类还没有被加载和链接,那就先进行加载和链接
- 假如类存在直接父类,并且这个父类还没有被初始化,那就先初始化直接父类
- 假如类中存在初始化语句,那就依次执行这些初始化语句
类的初始化时机:
1)主动使用(七种)
创建类的实例。
访问某个类或者接口的静态变量,或者对该静态变量赋值。
调用类的静态方法。
反射 (如Class.forName(“com.test.Test”))
初始化一个类的子类
Jav啊虚拟机启动时被标明为启动类的类(Java Test)
JDK1.7开始提供的动态 语言支持:
Java.lang.invoke.MethodHandle实例的解析结果REF_getStattic REF_putStatic REF_invokeStatic句柄对应的类如果没有初始化,则初始化(了解)
除了以上七中情况,其他使用Java类的方式都被看做是对类的被动使用,都不会导致类的初始化(指的是加载,连接,初始化这个步骤的初始化)
2)
验证第一条:在初始化一个类时,并不会先初始化它所实现的接口
public class MyTest5 {
/*
详情:http://blog.csdn.net/wzq6578702/article/details/79382182
*/
public static void main(String[] args) {
System.out.println(MyChild5.b);
}
}
interface MyParent5{
public static final int a =4;
public static Thread thread = new Thread(){
//代码块 当Thread的匿名类初始化的时候 代码块会被执行(每new一个类代码块都会执行一次)
{
System.out.println(“MyParent5 invoked!”);
}
};
}
class MyChild5 implements MyParent5{
public static int b = 5;
}
输出:
5
如果我们把MyParent5和MyChild5都改为Class呢?
答案是输出:
MyParent5 invoked!
5
因为子类的初始化会想初始化父类
然后我们如果把MyChild5的b改为【public static final int b = 5;】这样运行结果是什么呢?
答案是:
5
因为b是常量,常量会编译的时候就会放在MyTest5的常量池当中,甚至可以删除MyParent5和MyChild5的Class文件。
再进一步:
public class MyTest5 {
/*
详情:http://blog.csdn.net/wzq6578702/article/details/79382182
当一个接口初始化时并不要求其父接口完成了初始化
只有在真正用到父接口的时候(如引用接口中定义的常量时),才会初始化。
*/
public static void main(String[] args) {
System.out.println(MyChild5.b);
}
}
interface Grandapa{
public static Thread thread = new Thread(){
//代码块 当Thread的匿名类初始化的时候 代码块会被执行(每new一个类代码块都会执行一次)
{
System.out.println(“Grandapa invoked!”);
}
};
}
interface MyParent5 extends Grandapa{
public static final int a =4;
public static Thread thread = new Thread(){
//代码块 当Thread的匿名类初始化的时候 代码块会被执行(每new一个类代码块都会执行一次)
{
System.out.println(“MyParent5 invoked!”);
}
};
}
class MyChild5 implements MyParent5{
public static int b = 5;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后总结我的面试经验
2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
BAT面试经验
实战系列:Spring全家桶+Redis等
其他相关的电子书:源码+调优
面试真题:
说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
[外链图片转存中…(img-gJ25NMFz-1712094746950)]
BAT面试经验
实战系列:Spring全家桶+Redis等
[外链图片转存中…(img-J5WuaFd8-1712094746951)]
其他相关的电子书:源码+调优
[外链图片转存中…(img-KNUKowja-1712094746951)]
面试真题:
[外链图片转存中…(img-MVKMiFSM-1712094746951)]
[外链图片转存中…(img-ZMqSYDjn-1712094746952)]