ProgrammingJava開発者

JavaにおけるClassLoaderとは何か、その種類は何か、主な役割は何か?クラスローダーはクラスの隔離や互換性の問題にどのように影響するのか?

Hintsage AIアシスタントで面接を突破

回答

ClassLoaderは、JVMにおける特別なコンポーネントであり、クラスが初めて使用される際にバイトコードをメモリにロードする役割を担っています。これは、動的にさまざまなソース(ファイルシステム、ネットワーク、アーカイブなど)からクラスをロードすることを可能にします。

クラスローダーの種類:

  • Bootstrap ClassLoader — 基本的なJVMクラス(rt.jar)をロードするシステムローダー。
  • Extension ClassLoaderjre/lib/extパスから拡張機能をロードします。
  • System (Application) ClassLoader — classpathからアプリケーションクラスをロードします。
  • Custom ClassLoader — モジュラリティ、ホットデプロイ、プラグインに役立つユーザー定義のローダー。

ClassLoaderは委任を実装しています:まず親ローダーを介してクラスをロードしようとし(親優先)、失敗した場合にのみ自分自身を検索します。

クラスの隔離: 各クラスローダーは独自の"クラスのスコープ"を作成します。同名の2つのクラスを異なるローダーでロードした場合、JVM内で異なるタイプと見なされます。

カスタムローダーの作成例:

class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // クラスのバイトコードを検索してロードするコード return super.findClass(name); } }

トリックのある質問

異なるローダーでロードされた同名のクラスは、JVM内で同じクラスと見なされることがありますか?

回答: いいえ!JVMはクラスを(クラス名の完全名、クラスローダー)のペアでユニークなものと見なします。したがって、異なるローダーでロードされた同じクラスは異なるものと見なされます。


トピックの微妙な点を知らなかったための実際のエラーの例


物語

プラグインアーキテクチャをサポートするエンタープライズアプリケーションでは、プラグインが異なるクラスローダーでロードされていました。そのため、メインアプリケーションとプラグイン間でインターフェース(PluginInterface)タイプのオブジェクトを渡そうとするとClassCastExceptionが発生しました。なぜなら、同じインターフェースが異なるローダーでロードされていたからです。


物語

カスタムクラスローダーを使用する際に、親ローダーへの委任が実装されていませんでした。これにより、標準ライブラリクラスが再度ロードされ、奇妙なClassCastExceptionやLinkageErrorを引き起こしました。


物語

大規模なJava EEサーバーでは、異なるアプリケーションが同じライブラリの異なるバージョンをロードしていました。ローダーのチェーン設定に不注意があったため、アプリケーション間でクラスが交差し、一度は大規模なメモリリークとバージョンの競合による障害を引き起こしました。