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

目录

[TOC]

1 前言

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

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

2 类加载机制

2.1 什么是类加载机制

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

2.2 案例

    我们先来看一个案例

public class World{
  static{
     System.ou.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先告诉大家,最后的结果只会输出“word”,但是其中的原因你明白吗?我们接着往下看。

2.3 类加载的过程

image.png

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

    真实情况是加载、验证、准备、初始化、卸载这五个阶段的顺序是确定的,是依次有序的。但是解析阶段有可能会在初始化之后才会进行,这是为了支持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 双亲委派模型

image.png

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

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

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

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

3.3 破坏双亲委派模型

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

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

4 结语

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

    比如:

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

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

    我是moon,下期见,记得三连~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容