Java类加载机制高频面试题及详细答案(实战向)_第1页
Java类加载机制高频面试题及详细答案(实战向)_第2页
Java类加载机制高频面试题及详细答案(实战向)_第3页
Java类加载机制高频面试题及详细答案(实战向)_第4页
Java类加载机制高频面试题及详细答案(实战向)_第5页
已阅读5页,还剩1页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java类加载机制高频面试题及详细答案(实战向)一、基础概念类(初级必问)1.什么是类加载?什么时候会触发类加载?答案:类加载就是JVM把磁盘上的.class字节码文件,加载到内存中,转换成可以直接使用的java.lang.Class对象的过程。简单说,就是把静态的文件数据,变成内存中的运行时数据。触发类加载的核心场景(主动加载,会执行初始化):new创建对象实例调用类的静态方法、静态变量使用反射Class.forName()初始化子类时,会优先加载父类程序启动入口main方法所在类被动引用不会触发初始化:比如仅声明数组、常量编译期替换、父类静态变量子类访问,只会加载不会初始化。2.类加载的完整过程分为哪几步?各自做什么?答案:整体分为5个阶段:加载、验证、准备、解析、初始化。日常面试重点考后四个,合称链接阶段。加载:读取.class文件二进制数据,在内存方法区生成Class对象,此时类结构已经有了,但是未校验、未赋值。验证:保证字节码合法、安全,避免恶意/错误字节码破坏JVM,包含文件格式验证、元数据验证、字节码验证、符号引用验证。准备:给类静态变量分配内存,赋默认初始值(int=0、boolean=false、引用=null),不会赋代码里写的初始值。解析:把代码里的符号引用(字面量地址)替换成直接的内存指针引用,运行时可以直接定位对象、方法、变量。初始化:最后一步,执行静态代码块、静态变量赋值操作,真正执行开发者写的静态逻辑,也是唯一主动加载会触发的阶段。3.说说准备阶段和初始化阶段的变量赋值区别?答案:很多人容易混淆这两个阶段的赋值:准备阶段:只给静态变量赋JVM默认值。比如staticinta=10;,准备阶段a=0。初始化阶段:才会执行代码赋值,把a改成10,同时执行静态代码块。如果是finalstatic编译期常量,编译阶段就直接赋值,不会走准备和初始化赋值。二、类加载器体系(核心高频)4.JVM有哪些类加载器?各自加载什么类?答案:JDK8及以前三层核心加载器,从上到下层级:启动类加载器(Bootstrap):C++实现,JVM内置,加载JDK核心底层类,比如rt.jar里的java.lang、java.util包,开发者无法直接获取它的实例。扩展类加载器(Extension):Java实现,加载JDK扩展包的类,jre/lib/ext目录下的jar包。应用类加载器(App/System):我们最常用的,加载项目classpath下的自定义类、第三方依赖jar包,是默认的类加载器。除此之外还有自定义类加载器,由开发者自己实现,用于热加载、隔离加载、加密解密class文件等场景。注:JDK9+模块化之后,层级略有变化,但面试默认问JDK8体系。5.什么是双亲委派机制?工作流程是什么?答案:双亲委派是类加载的核心机制,父加载器不是继承关系,是组合委派关系。工作流程:应用类加载器收到加载请求,不会自己先加载,先委托父加载器(扩展类加载器)。扩展类加载器继续向上委托给启动类加载器。启动类加载器是顶层,无法继续委派,尝试自己加载。如果顶层加载不了,逐层向下退回,由子类加载器尝试加载。总结:向上委派,向下加载。6.双亲委派机制的作用和好处?答案:核心两个作用,面试必背:保证核心类安全,防止篡改:比如我们自己写一个java.lang.String类,不会被加载。因为启动类加载器已经加载了系统原生String,优先使用顶层加载器的类,避免自定义恶意核心类覆盖原生类。保证类全局唯一,避免重复加载:同一个类只会被顶层能加载的加载器加载一次,避免不同加载器重复加载导致类冲突。7.能不能打破双亲委派机制?怎么打破?答案:可以打破,双亲委派是Java的默认实现,不是语法强制规则。原理:重写自定义类加载器的loadClass()方法,去掉向上委派的逻辑,自己优先加载,再委托父加载器。常见打破场景:Tomcat:自定义类加载器,优先加载项目自己的jar,再加载容器公共jar,实现web应用类隔离,不同项目同名类不冲突。SPI机制:线程上下文类加载器,核心接口由启动类加载器加载,实现类由应用加载器加载,反向委派打破双亲委派。热部署、热加载框架:自定义加载器动态加载新class文件。8.为什么Tomcat要打破双亲委派?答案:原生双亲委派是父优先子,Tomcat需要子优先父。因为Tomcat部署多个web项目,不同项目可能依赖不同版本的同一个jar包。如果用默认双亲委派,所有项目共用父加载器的jar,会出现版本冲突、类覆盖问题。Tomcat自定义WebappClassLoader,优先加载当前项目的class和jar,再委托父加载器,实现项目类隔离、版本隔离。三、深度进阶面试题(中高级)9.什么是类的全盘负责、单一双亲、缓存机制?答案:全盘负责:一个类加载器加载某个类后,该类依赖的其他类、引用的类,默认也由这个加载器负责加载,除非主动委派其他加载器。单一双亲:每个类加载器只有一个父加载器,不会多父,保证委派链路唯一。缓存机制:所有加载过的Class对象都会被缓存,下次使用直接从缓存取,不会重复加载,这也是类只加载一次的核心原因。10.同一个类,两个不同类加载器加载,算不算同一个类?答案:不算,完全是两个不同的类。JVM判定两个类是否相等,必须同时满足两个条件:类的全限定名完全一致加载该类的类加载器是同一个不同加载器加载的同名类,class对象不同,相互赋值会报类型转换异常,这也是Tomcat项目隔离、OSGI模块隔离的底层原理。11.说说Class.forName()和newClassLoader().loadClass()的区别?答案:Class.forName():默认会执行类加载的初始化阶段,会触发静态代码块、静态变量赋值。JDBC驱动注册就是用这个方法,需要执行静态代码块注册驱动。loadClass():只执行加载、链接阶段,不会执行初始化,不触发静态代码块。适合只需要获取Class对象,不需要初始化的场景。12.什么是热加载?底层原理是什么?答案:热加载就是程序运行过程中,不重启服务,动态更新class文件,让新代码生效。底层原理:JVM的Class一旦被加载,无法修改,只能重新加载。自定义类加载器重写loadClass方法,每次检测class文件是否更新,如果变更,就新建一个类加载器实例重新加载该类。旧的Class对象和类加载器会被GC回收,实现代码动态替换。常见场景:IDEA热部署、JRebel、开发环境热更新。13.自定义类加载器怎么实现?核心步骤?答案:核心两步:继承ClassLoader类重写findClass()方法(不建议重写loadClass,破坏双亲委派)实现逻辑:读取磁盘/网络的class字节码,调用defineClass方法,把字节码转为Class对象。如果需要打破双亲委派,才重写loadClass方法,修改委派逻辑。14.线程上下文类加载器是什么?解决了什么问题?答案:线程上下文类加载器默认是应用类加载器。它的作用是反向打破双亲委派,解决SPI机制的类加载问题。场景举例:JDBC。JDBC的核心接口Driver在rt.jar中,由启动类加载器加载;而mysql的驱动实现类在第三方jar,启动类加载器加载不到。所以通过线程上下文类加载器(应用加载器)反向加载实现类,解决顶层加载器无法加载下层实现类的问题。四、常见坑点&面试追问15.static代码块、构造代码块、构造方法的执行顺序和类加载的关系?答案:类加载初始化阶段:执行静态变量赋值、静态代码块(优先执行)。创建对象阶段:先父类构造代码块、构造方法,再子类构造代码块、构造方法。完整顺序:父静态>子静态>父构造代码块>父构造方法>子构造代码块>子构造方法。16.类加载会不会加载接口的静态代码块?抽象类呢?答案:接口:JDK8之后接口可以有静态方法、静态常量,但没有静态代码块,且接口不会在子类加载时被初始化,只有主动调用接口静态方法才会初始化。抽象类:和普通类一样

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论