Android:知道类加载过程面试还是卡壳?干货总结,一网打净“类”的基础知识

public static int value3 = 300;

public int value5 = 500;

static{

value3 = 301;

System.out.println(“2”);

}

{

value3 = 302;

System.out.println(“5”);

}

public Student(){

value3 = 303;

System.out.println(“6”);

}

}

  • 首先是类装载,链接(验证、准备、解析)。

  • 当执行类准备过程中,会对类中的静态变量分配内存,并设置为初始值也就是“0值”。比如上述代码中的value1,value3,会为他们分配内存,并将其设置为0。但是注意,用final修饰静态常量value2,会在这一步就设置好初始值102。

  • 初始化阶段,会执行类构造器<clinit>方法,其主要工作就是初始化类中静态的(变量,代码块)。但是在当前类的<clinit>方法执行之前,会保证其父类的<clinit>方法已经执行完毕,所以一开始会执行最上面的父类Object的<clinit>方法,这个例子中会先初始化父类Person,再初始化子类Student。

  • 初始化中,静态变量和静态代码块顺序是由语句在源文件中出现的顺序所决定的,也就是谁写在前面就先执行谁。所以这里先执行父类中的value1=100,value1 = 101,然后执行子类中的value3 = 300,value3 = 301

  • 接着就是创建对象的过程,也就是类的实例化,当对象被类创建时,虚拟机会分配内存来存放对象自己的实例变量和父类继承过来的实例变量,同时会为这些事例变量赋予默认值(0值)。

  • 分配完内存后,会初始化父类的普通成员变量(value4 = 400),和执行父类的普通代码块(value1=102),顺序由代码顺序决定。

  • 执行父类的构造函数(value1 = 103)

  • 父类实例化完了,就实例化子类,初始化子类的普通成员变量(value5 = 500),执行子类的普通代码块(value3 = 302),顺序由代码顺序决定。

  • 执行子类的构造函数(value3 = 303)

所以上述例子打印的结果是:

123456

总结一下执行流程就是:

  1. 父类静态变量和静态代码块;
  1. 子类静态变量和静态代码块;
  1. 父类普通成员变量和普通代码块;
  1. 父类的构造函数;
  1. 子类普通成员变量和普通代码块;
  1. 子类的构造函数。

最后,大家再结合流程图好好梳理一下:

类初始化的触发时机

在同一个类加载器下,一个类型只会被初始化一次,刚才说到new对象是类初始化的一个判断时机,其实一共有六种能够触发类初始化的时机:

  • 虚拟机启动时,初始化包含 main 方法的主类;

  • 遇到 new等指令创建对象实例时,如果目标对象类没有被初始化则进行初始化操作;

  • 当遇到访问静态方法或者静态字段的指令时,如果目标对象类没有被初始化则进行初始化操作;

  • 子类的初始化过程如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化;

  • 使用反射API 进行反射调用时,如果类没有进行过初始化则需要先触发其初始化;

  • 第一次调用java.lang.invoke.MethodHandle 实例时,需要初始化 MethodHandle 指向方法所在的类。

多线程进行类的初始化会出问题吗

不会,<clinit>()方法是阻塞的,在多线程环境下,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>(),其他线程都会被阻塞。

类的实例化触发时机

  • 使用new关键字创建对象

  • 使用Class类的newInstance方法,Constructor类的newInstance方法(反射机制)

  • 使用Clone方法创建对象

  • 使用(反)序列化机制创建对象

<clinit>()方法和<init>()方法区别。

  • <clinit>()方法发生在类初始化阶段,会执行类中的静态类变量的初始化和静态代码块中的逻辑,执行顺序就是语句在源文件中出现的顺序。

  • <init>()方法发生在类实例化阶段,是默认的构造函数,会执行普通成员变量的初始化和普通代码块的逻辑,执行顺序就是语句在源文件中出现的顺序。

在类都没有初始化完毕之前,能直接进行实例化相应的对象吗?

刚才都说了先初始化,再实例化,如果这个问题可以的话那不是打脸了吗?

没错,要打脸了哈哈。

确实是先进行类的初始化,再进行类的实例化,但是如果我们在类的初始化阶段就直接实例化对象呢?比如:

public class Run {

public static void main(String[] args) {

new Person2();

}

}

public class Person2 {

public static int value1 = 100;

public static final int value2 = 200;

public static Person2 p = new Person2();

public int value4 = 400;

static{

value1 = 101;

System.out.println(“1”);

}

{

value1 = 102;

System.out.println(“2”);

}

public Person2(){

value1 = 103;

System.out.println(“3”);

}

}

嘿嘿,这时候该怎么打印结果呢?

按照上面说过的逻辑,应该是先静态变量和静态代码块,然后普通成员变量和普通代码块,最后是构造函数。

但是因为静态变量又执行了一次new Person2(),所以实例化过程被强行提前了,在初始化过程中就进行了实例化。这段代码的结果就变成了:

23123

所以,实例化不一定要在类初始化结束之后才开始初始化,有可能在初始化过程中就进行了实例化。

类的初始化过程与类的实例化过程的异同?

学了上面的内容,这个问题就很简单了:

  • 类的初始化,是指在类装载,链接之后的一个阶段,会执行<clinit>()方法,初始化静态变量,执行静态代码块等。

  • 类的实例化,是指在类完全加载到内存中后创建对象的过程,会执行<init>()方法,初始化普通变量,调用普通代码块。

一个实例变量在对象初始化的过程中最多可以被赋值几次?

那我们就试试举例出最多的情况,其实也就是每个要经过的地方都对实例变量进行一次赋值:

  • 1、对象被创建时候,分配内存会把实例变量赋予默认值,这是肯定会发生的。

  • 2、实例变量本身初始化的时候,就给他赋值一次,也就是int value1=100。

  • 3、初始化代码块的时候,也赋值一次。

  • 4、构造函数中,在进行赋值一次。

一共四次,看代码:

public class Person3 {

public int value1 = 100;

{

value1 = 102;

System.out.println(“2”);

}

public Person3(){

value1 = 103;

System.out.println(“3”);

}

}

面试前做好准备战!

接下来将分享面试的一个复习路线,如果你也在准备面试但是不知道怎么高效复习,可以参考一下我的复习路线,有任何问题也欢迎一起互相交流,加油吧!

这里给大家提供一个方向,进行体系化的学习:

1、看视频进行系统学习

前几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。

另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你。

2、进行系统梳理知识,提升储备

最后

上面这些公司都是时下最受欢迎的互联网大厂,他们的职级、薪资、福利也都讲的差不多了,相信大家都是有梦想和野心的人,心里多少应该都有些想法。

也相信很多人也都在为即将到来的金九银十做准备,也有不少人的目标都是这些公司。

我这边有不少朋友都在这些厂工作,其中也有很多人担任过面试官,上面的资料也差不多都是从朋友那边打探来的。除了上面的信息,我这边还有这些大厂近年来的面试真题及解析,以及一些朋友出于兴趣和热爱一起整理的Android时下热门知识点的学习资料

部分文件:


网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

理的Android时下热门知识点的学习资料**。

部分文件:
[外链图片转存中…(img-dpWxgGUX-1714478203456)]
[外链图片转存中…(img-XYas5rbh-1714478203457)]
[外链图片转存中…(img-HWN9oJCb-1714478203457)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值