クラスローダの概要
JVMは、Javaクラスローダによって他のBootstrapClassLoaderに加えて、三つの重要なクラスローダを構築し、すべてから継承を実装しますjava.lang.ClassLoader
:
- BootstrapClassLoader(ブートクラスローダー):C ++によって実現トップレベルクラスのロードは、ロードする責任がある
%JAVA_HOME%/lib
JARパッケージおよびクラスまたはディレクトリ、または-Xbootclasspath
クラスパスで指定されたパラメータのすべてを。 - ExtensionClassLoader(拡張クラスローダ):ディレクトリのロードを主に担当
%JRE_HOME%/lib/ext
のjarパッケージとクラスディレクトリ、またはjava.ext.dirs
パスを指定したシステム変数の下のjarパッケージを。 - AppClassLoader(アプリケーションクラスローダ):ユーザーの皆様ローダーのためには、アプリケーションのクラスパスに現在のすべてのjarパッケージおよびクラスをロードする責任があります。
親委任モデルが導入します
各クラスは、そのクラスローダを持っています。職場でのシステムClassLoderデフォルトの親委任モデルを使用して 。これは、クラスがロードされると、システムは最初に、現在のクラスがあまりにもロードされているかどうかを判断しますです。クラスが直接返されます、またはロードしようとしますロードされています。ロードされると、要求はまず親クラスローダに委譲される loadClass()
プロセス、そう最終的にすべての要求は、ブートクラスローダのトップに転送する必要があります BootstrapClassLoader
インチ 親クラスローダが処理できない場合は、自分自身だけで扱うことができます。親クラスローダがnullの場合は、ブートクラスローダを使用する BootstrapClassLoader
親クラスローダとして。
各クラスローダは、親クラスローダを持って、私たちは、次の手順を確認する必要があります。
パブリック クラスClassLoaderDemo { 公共 静的 ボイドメイン(文字列[]引数){ するSystem.out.println( "ClassLodarDemoのClassLoaderは" + ClassLoaderDemo。クラス.getClassLoader())。 System.out.println( "ClassLodarDemoのクラスローダの親である" + ClassLoaderDemo。クラス.getClassLoader()のgetParent()); System.out.println( + ClassLoaderDemo "ClassLodarDemoのClassLoaderの祖父母がある"。クラス.getClassLoader()のgetParent()のgetParent()。。); } }
ClassLodarDemoのClassLoaderはsun.misc.Launcher$AppClassLoader@18b4aac2ある sun.misc.Launcher$ExtClassLoader@1b6d3586さClassLodarDemoのクラスローダの親 ClassLodarDemoのClassLoaderザ祖父母がnull
AppClassLoader
親クラスローダExtClassLoader
ExtClassLoader
の親クラスローダがnull、nullがあることを意味しませんExtClassLoader
親クラスローダを、しかし BootstrapClassLoader
。
両親委任利益モデル
、Javaプログラムの安定動作を確保するために、親委任モデル繰り返し荷重クラス避けるために(異なるクラス間を区別するためのJVMの方法は、クラス名のみに基づいていない、同じクラスファイルは、異なるクラスローダを生成するためにロードされている2つの異なるクラス) 、だけでなく、コアのJava APIを確保するために改ざんされていません。親委譲モデルが、各クラスローダがロードしないようにした場合、自分の言葉は、私たちが書くために呼ばれているなど、いくつかの問題になる java.lang.Object
プログラムが実行されているときに、システムが異なるの数が表示されます、クラスを Object
クラスを。
ターン:Javaのクラスローダ原則の詳細な分析
まず、クラスローダ?何をされた
プログラムが実行されている場合我々は、すべての我々はJavaプログラムを書くとき、チューブは完全なJavaアプリケーションやBS、CSアプリケーションではないことを知っているが、作られた.classファイルの数によって編成されています、それはシステムに関連する機能を呼び出すための入力プログラムの関数を呼び出すと、これらの機能があれば、クラスメソッド、さらにファイルと呼ばれるように、このクラスからそう頻繁にファイル間で異なるクラスファイルにパッケージ化されています別のファイルが存在しない、システムは例外をトリガします。起動時のプログラム、およびので、使用するクラスファイルのプログラムを一度にすべてをロードしませんが、Javaのクラスローディング機構(クラスローダ)で必要なプログラムが動的にメモリにクラスファイルをロードするためにクラスファイルがメモリにロードされた後にのみ、別のクラスによって参照されます。だから、ClassLoaderクラスは、動的に使用しているメモリにファイルをロードするために使用されます。
1.原則として紹介し
たクラスを検索するために、親委任モデルを使用してClassLoaderを、各ClassLoaderインスタンスの親クラスローダへの参照が(継承されていない関係の関係が含まれている)があり、内蔵された仮想マシンのクラスローダ(ブートストラップクラスローダ)なし親クラスローダ自体が、上のクラスローダの親クラスローダの他の例として使用することができます。クラスローダのインスタンスがクラスをロードする必要がある場合、それはクラスの前に人を検索しようと、最初のタスクは、親クラスローダによってそれに委ね、このプロセスは、まず最上位で、上から下に検討されますそれを得るためにロードされていないならば、委任し、ロードするためにアプリケーションクラスローダに転送にロードされていない場合は、ロードしようとしたクラスローダブートストラップクラスローダへの負荷がない場合、ロードしようとして拡張クラスローダにタスクを置くが、返されますファイルシステムやネットワークのURLロードされたクラスによって割り当てられたイニシエータなど、。彼らはこのカテゴリーにロードされていない場合は、ClassNotFoundExceptionがスローされます。そうしないと、このクラスは、クラス定義を生成し、メモリにロードし、メモリにこのクラスのクラスインスタンスオブジェクトを返すでしょう。
2.なぜ親はそれを任せ、このモデルを使用できますか?
再びロードされた不要の子クラスローダがないとき父は、クラスをロードしたときに、繰り返し荷重がなくなるため。セキュリティ上の理由から、私たちは、あなたがこの委任モデルを使用しない場合、我々は常に動的にJavaのコアAPIが定義されて代わるカスタムString型を使用することができますので、非常に大きなセキュリティ上のリスクがあるだろう、と両親は委託、想像します文字列が既に起動時にブートストラップクラスローダ(Bootstrcpクラスローダ)によってロードされたための方法、あなたはJDKクラスローダを変更しない限り、そのユーザー定義のクラスローダは、文字列の負荷を書いたことはありません、このような状況を回避することができますデフォルトの検索アルゴリズムクラス。
3、しかし、検索クラスのJVM、2クラスが同じであるかを決定する方法ですか?
JVMクラスは、同じ2つのクラスの名前かどうかを判断するために、だけでなく、クラスローダの同じインスタンスをロードするかどうかを判断するだけではなく、2つが同じであるかどうかを判断します。のみ両方満たす場合には、JVMクラスは、これらの2つが同じであることを考えます。
第四に、独自のクラスローダを定義
JVMがデフォルトのクラスローダを提供しているので、なぜ自分のクラスローダーが行う定義する必要がありますか?
クラスローダJavaが提供するデフォルトのため、我々のようなクラスまたはjar他の場所、ロードしたい場合にのみ、指定したディレクトリにjarファイルやクラスをロード:私はダイナミック後にメモリにロードされ、ネットワーク上のクラスファイルをロードするには私のビジネスロジックを実現するために、クラスでこのメソッドを呼び出します。この場合、デフォルトのクラスローダは、我々のニーズを満たすことができないので、あなたはあなた自身のClassLoaderを定義する必要があります。
自分のクラスローダを2つの段階に分けて定義します。
1、相続はjava.lang.ClassLoader
2、親クラスのオーバーライドにfindClass
読者はなぜのみにfindClassメソッドを書き換え、非常に多くの方法の親があり、ここで問題を有していても良いですか?
JDK loadClassメソッドがないクラスのloadClassメソッドを検索するとき、検索アルゴリズムのClassLoaderクラスに達成するために私たちを助けているので、loadClassメソッドは、クラスを検索するにfindClassの道と呼ばれているので、私たちは、このメソッドをオーバーライドする必要があります。特別な要件場合は、一般的にはloadClass検索アルゴリズムのクラスを書き換えることはお勧めしません。