Java 面试题

Java类加载机制和双亲委派

讲讲双亲委派模型。Tomcat为什么要打破它?

为什么面试官会问这道题

考你是不是真懂类加载隔离——插件系统、应用服务器、热重载的基石。

如何回答

  1. 1

    三层内置加载器:Bootstrap(rt.jar,C++原生)、Extension/Platform(jre/lib/ext或模块)、Application(classpath)。

  2. 2

    双亲委派:先让父加载器找,父找不到自己才加载。目的:核心类(java.lang.Object)永远来自Bootstrap,防止被冒充。

  3. 3

    Tomcat的WebappClassLoader对WEB-INF/classes反着来——webapp自己先加载,这样不同war能在同一个JVM里用不同版本的库。

  4. 4

    SPI(ServiceLoader / JDBC Driver)也打破委派,靠Thread.currentThread().getContextClassLoader()——让Bootstrap里的核心代码能找到应用classpath下的实现。

  5. 5

    同一个.class被不同classloader加载=两个不同的Class对象,名字一样也会ClassCastException。插件隔离的关键认知。

参考回答示例

默认就是双亲委派——Bootstrap→Extension→Application,每层先问父亲、父亲说没有自己才找。保证java.lang.*不会被恶意jar替换掉。两个经典打破:Tomcat的WebappClassLoader对WEB-INF/classes先自己加载,所以不同war能带不同版本的Jackson;SPI靠线程上下文类加载器让Bootstrap里的JDBC API能找到应用classpath下的驱动实现。类的身份=类加载器+全限定名,同一个类两个加载器就是两个Class对象——这也是热重载框架里跨重载持引用会ClassCastException的原因。

实用技巧

  • Java 9+把Extension换成了Platform(模块化),层级思想一样。

  • ClassNotFoundException vs NoClassDefFoundError:前者是"从来没找到",后者是"找到过但链接失败或加载器可见性问题"。

  • 即答侠会把这题和Tomcat/SPI实例绑在一起练——面试官一听就知道你搞过插件系统不是背书的。

常见问题

能自己写类加载器吗?

能,继承ClassLoader重写findClass。插件框架、热重载(JRebel)、OSGi都是这么干的。

为什么JDBC DriverManager要用上下文类加载器这招?

DriverManager在rt.jar(Bootstrap),驱动实现在应用classpath(Application)。Bootstrap看不见Application,只能通过线程上下文加载器"向下"去拿。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠