专栏首页moon聊技术moon不讲武德!!!一个类加载机制给面试官说蒙了!!

moon不讲武德!!!一个类加载机制给面试官说蒙了!!

目录

  • 目录
  • 1 前言
  • 2 类加载机制
    • 2.1 什么是类加载机制
    • 2.2 案例
    • 2.3 类加载的过程
  • 3 类加载器
    • 3.1 什么是类加载器
    • 3.2 双亲委派模型
    • 3.3 破坏双亲委派模型
  • 3 结语

1 前言

距离上次发表文章已经一周了,本来是打算早点肝出来的,但是由于不可抗力因素,年终了,需求急剧增加,再加上moon得给自己留出点学习时间,这篇文章也就拖到了现在,羞愧羞愧。

今天我们来聊点基础却又不简单的东西,类加载机制,也是为moon的下一篇文章做个铺垫.

2 类加载机制

2.1 什么是类加载机制

java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被jvm可以直接使用的类型,这个过程就可以成为虚拟机的类加载机制。

2.2 案例

我们先来看一个案例

public class World{
  static{
     System.out.println("hello");
  }
  public static final String WORLD = "world";
}
public class Home extends World{
  static{
     System.ou.println("home");
  }
}
public  class Test{
  public static void main(String[] args){
      System.out.println(Home.word);
  }
}

上面这个代码,究竟会输出什么?答案moon先告诉大家,最后的结果只会输出“world”,但是其中的原因你明白吗?我们接着往下看。

2.3 类加载的过程

这是一张很经典的图,标明了一个类的生命周期,而很多人一眼看过去就以为明白了类的生命周期,但是这只是其中一种情况。

真实情况是加载、验证、准备、初始化、卸载这五个阶段的顺序是确定的,是依次有序的。但是解析阶段有可能会在初始化之后才会进行,这是为了支持java动态绑定的特性。

动态绑定: 在运行时根据具体对象的类型进行绑定。提供了一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。

举个例子:

  class a{
    void test(){};
  }
  class b extends  a{
    void test(){};
  }
  class c {
    main(){
      A a = new B();
      a.test();
    }
  }

上述代码就可以很快的让你理解动态绑定了。

A a = new B();这行代码在编译器的时候程序其实并不知道new B()真正的引用是谁,在执行a.test()时 ,也就是直到运行期间才确定,调用的是子类的test(),其实这就是动态绑定。

《java虚拟机规范》规定,只有以下6种情况才会触发初始化:(以下参考《深入理解java虚拟机》)

  • 遇到 new、getstatic、putstatic 或 invokestatic 这 4 条字节码指令;
  • 使用 java.lang.reflect 包的方法对类进行反射调用的时候;(这里可能就会出现面试题,反射的缺点是什么
  • 当初始化一个类的时候,发现其父类还没有进行初始化的时候,需要先触发其父类的初始化;
  • 当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先初始化这个类;
  • 当使用 JDK 1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getStatic、REF_putStatic、REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有初始化。
  • 使用java8新加入的default默认方法,如果这个接口的实现类发生了初始化,那么该接口要在其之前被初始化。

我们回到刚才的案例,正常来说当我们执行Home.word时,World类就应该已经被加载了,但是关键点在于word这是个静态字段,而且Home这个类是继承了World类,而针对于静态变量,只有直接定义这个字段的类才会被初始化,所以说,如果这个静态变量没有被final修饰,那么正常情况下应该输出“hello”,“world",但是,由于是被final修饰的,就会在编译阶段直接存储在常量池中,最终调用的情况其实是Test类对常量池的引用,这下大家应该明白了。

3 类加载器

3.1 什么是类加载器

实现"通过一个类的全限定名来获取描述该类的二进制流"的动作的代码就叫做类加载器。

简单点来说,就是我知道你的名字后,我能知道你的全部,完成这个操作的就是"类加载器"。

3.2 双亲委派模型

这是一张很经典的图,通常情况下,各个类加载器的协作关系就是这样的。

双亲委派模型:简而言之,就是说一个类加载器收到了类加载的请求,不会自己先加载,而是把它交给自己的父类去加载,层层迭代

用上图来说明就是如果应用程序类加载器收到了一个类加载的请求,会先给扩展类加载器,然后再给启动类加载器,如果启动类加载器无法完成这个类加载的请求,再返回给扩展类加载器,如果扩展类加载器也无法完成,就返回给应用类加载器。

那么双亲委派模型的好处是什么?说这个问题前我要先和大家说一个概念,jvm中类的唯一性是由类本身和加载这个类的类加载器决定的,简单的说,如果有个a类,如果被两个不同的类加载器加载,那么他们必不相等。你看到这里会不会想到所有类的父类都是Object是怎么实现的了吗?是因为无论哪一个类加载器加载Object类,都会交给最顶层的启动类加载器去加载,这样就保证了Object类在jvm中是唯一的。

3.3 破坏双亲委派模型

当然,不是所有的类加载器都是遵循双亲委派模型的,和大家简单描述一个场景。

我们在最初学习的时候肯定学习过JDBC,其连接数据库的方式其实是通过一个Driver类去实现的,由于原生的JDBC中的类是放在rt.jar包的,是由启动类加载器进行类加载的,且需要动态去加载不同数据库类型的Driver类,而mysql-connector-.jar中的Driver类是用户自己写的代码,所以启动类加载器是不能进行加载的,需要由应用程序类加载器进行加载。此时,通过线程上下文类加载器获得应用程序类加载器,通过应用程序类加载器去加载这个Driver类,从而避开了双亲委派模型的局限性

3 结语

其实这些东西都是死记硬背的东西,尤其是类加载的过程,其中有很多东西是没有什么值得关注的,只是为了应付面试,但是你需要明白的是为什么会这样设计,设计的好处是什么

比如:

为什么解析阶段有可能会在初始化阶段后才执行? 双亲委派模型的好处是什么?为什么会这样设计? 为什么会出现破坏双亲委派的模型?是解决了什么问题?

大部分人学习一个新知识可能都是死记硬背,加上简单的理解,但是其实代码的世界很多地方都是互通的,要学会提取知识的精华,也就是思想,在自己的知识库中去训练一个模型,当你再学一个新知识的时候,很有可能你就会发现,这个知识,虽然我没有完全了解,但是它的设计思想我以前学过。真实的情况就是这样,尤其是你学到越多的框架,越多的技能,这种感知就会越来越深,一定要学会提炼,提炼,再提炼

本文分享自微信公众号 - moon聊技术(onetraveller_llxz),作者:moon聊技术

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-11-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 面试官问我:Object o = new Object() 占用了多少个字节?

    最近马师傅火的不要不要的,虽然没有抢到耗子尾汁的商标注册权,但是必须得蹭一波马师傅的热度,下面就是闪电五连鞭的教学环节,你准备好了吗!

    Java宝典
  • 从人到电子人的科技之路|洞见

    刘彩红 ThoughtWorks 2016年5月底,ThoughtWorks在纽约办公室再次倾听并访问了艺术家Neil Harbisson和Moon Riba...

    ThoughtWorks
  • 业界 | 千人签署阻止「杀人机器」承诺,马斯克、哈萨比斯位列其中

    一名男子在武器交易会上走过武装机器人系统。摄影:Brendan Smialowski/ Bloomberg /Getty Images

    机器之心
  • Nature《自然》| 美国航天局真的能在2024年前让人类重返月球吗?

    Donald Trump wants US astronauts back on the Moon. But his ambitious plan faces ...

    HuangWeiAI
  • 周志华、Hinton等50多名学者联名抵制韩国研发“杀人机器人”

    新智元
  • 史上第一次!委内瑞拉总统遭到无人机炸弹袭击,士兵溃不成军

    【新智元导读】刚刚,委内瑞拉总统在国民警卫队成立81周年庆祝仪式上发表讲话时,突然遭到携带炸药的无人机袭击,电视直播记录下了全过程,原本整齐列队的士兵像流水一样...

    新智元
  • qt王者荣耀皮肤抽奖器

    说一下过程吧,第一步,就是先准备好皮肤的图片,皮肤的图片在王者荣耀的官网是可以下载的,但是过百的下载量确实有点大了,动了个小心思,网上找了一个用py写的爬虫...

    花狗Fdog
  • 当机器人能决定人类生死时,我们还能信赖它吗?

    随着人工智能和机器学习的发展,机器人越来越多地承担起更加重要的工作,如外科手术、自动驾驶、战场作战,甚至能决定人类的生死,那么——我们能信赖机器人吗? 按大众对...

    机器人网
  • 新突破!机器人可以注射到人体内,消灭癌细胞

    提起机器人,人们的第一印象多半是那些给人“恐怖谷”感觉的笨拙人形钢铁之躯,但这些机器人的贡献可能只局限于“解除人类劳动力”,而最近,另一种机器人正在悄悄的为人类...

    机器人网
  • Mybatis学习的一些细节

    一.mybatis 基本配置 最近几天一直在学习mybatis,看了一些源码,本文讲述mybatis的一些基本配置和基本的用法和注意到一些细节。个人时间和精力有...

    方志朋
  • 无人机袭击了委内瑞拉总统,我们该如何防范从天而降的杀人武器?

    【新智元导读】委内瑞拉总统遭无人机袭击,我们该如何防范从天而降的武器?介绍了当前无人机武器在战场上的一系列应用,以及相应的防范手段,比如自动追踪软件、电子干扰设...

    新智元
  • 【榜单】史上最经典36部AI电影大放送

    新智元
  • 【远程办公】无需公网、无需服务端5分钟实现内网穿透

    上文 《【远程办公】5分钟实现内网穿透》有个老哥私聊了我一下 好吧,正如这个老哥的需求

    冷冷
  • 腾讯和Science推青少年科学看点榜单:120万中国孩子最关注天文学

    ? 今年榜单囊括了天文学、数学物理学、生命科学和化学等四大领域的最新前沿科学突破,一些话题关乎人类对广袤宇宙的探索,例如首张黑洞照片面世,嫦娥四号在月球背面着...

    鹅老师
  • 爬虫实例九:探索神秘的原神世界

    《原神》是一款开放世界冒险游戏,有着丰富多彩的元素,可爱帅气的人物角色,五彩斑斓的风景,那我们怎么使用python爬虫打开“原神世界”的大门呢?我们今天就来用p...

    远方的星
  • 六冠王奇迹的背后,是德甲AI加持的足球

    有关德国足球,人们的印象可能是快速的攻防节奏、领先的教练发展体系,以及各种科学到极致的训练和健身计划。德甲球队为我们贡献了高水平的比赛,最近一次欧洲冠军联赛、世...

    机器之心
  • 图灵 V.S 冯诺依曼

    图灵和冯诺依曼都对计算机的发展做出了杰出的贡献,那么这两位大神级的人物,谁更配得上计算机之父呢?

    程序猿石头
  • 华引芯孙雷蒙:主攻高端LED芯片,推出全球可量产的最小尺寸Mini LED | 镁客请讲

    在刚刚于武汉举办的光博会上,光源供应厂商华引芯首发了全球可量产的最小尺寸Mini LED产品,这也意味着国内创企在高端LED芯片上取得了新进展。

    镁客网
  • 一个拯救微软帝国复兴的人-纳德拉

    T客汇官网:tikehui.com 原作者:Andrew Nusca 编译 | 李哲 ? 都柏林的秋日午后,狂风四起。飘忽而至的云驱散了落日的余晖,残余的灰色...

    人称T客

扫码关注云+社区

领取腾讯云代金券