web-dev-qa-db-ja.com

Java ClassLoaderとは何ですか?

いくつかの簡単な文章で、Java ClassLoader、それはいつ使用され、なぜですか?

OK、ウィキの記事を読みました。 ClassLoaderはクラスをロードします。 OK。したがって、jarファイルを含めてインポートすると、ClassLoaderがジョブを実行します。

このClassLoaderを使用する必要があるのはなぜですか?私は一度も使ったことがないし、存在することも知りませんでした。

問題は、なぜClassLoaderクラスが存在するのかということです。また、実際にどのように使用していますか? (場合があります、私は知っています。)

167
EugeneP

このニースから tutorial Sunから:

動機

CやC++などの静的にコンパイルされたプログラミング言語で記述されたアプリケーションは、ネイティブのマシン固有の命令にコンパイルされ、実行可能ファイルとして保存されます。コードを実行可能なネイティブコードに結合するプロセスはリンクと呼ばれます。リンク-個別にコンパイルされたコードと共有ライブラリコードをマージして実行可能アプリケーションを作成することです。これは、Javaなどの動的にコンパイルされたプログラミング言語では異なります。 Javaでは、Javaコンパイラによって生成された.classファイルは、Java Virtual Machine(JVM)にロードされるまでそのまま残ります。つまり、リンクプロセスは実行時にJVMによって実行されますクラスは「必要に応じて」JVMにロードされますロードされたクラスが別のクラスに依存する場合、そのクラスもロードされます。

Javaアプリケーションが起動されると、最初に実行するクラス(またはアプリケーションへのエントリポイント)は、main()というpublic static voidメソッドを持つクラスです。このクラスは通常、他への参照を持ちます。クラス、および参照されたクラスをロードするすべての試みは、クラスローダーによって実行されます。

この再帰的なクラスの読み込みと、一般的なクラスの読み込みの考え方を理解するには、次の単純なクラスを検討してください。

_public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}
_

-verbose:classコマンドラインオプションを指定してこのクラスを実行し、どのクラスがロードされているかを出力する場合、次のような出力が得られます。リストが長すぎてここに表示できないため、これは単なる部分的な出力であることに注意してください。

_prmpt>Java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded Java.lang.Object from shared objects file]
[Loaded Java.io.Serializable from shared objects file]
[Loaded Java.lang.Comparable from shared objects file]
[Loaded Java.lang.CharSequence from shared objects file]
[Loaded Java.lang.String from shared objects file]
[Loaded Java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded Java.lang.reflect.Type from shared objects file]
[Loaded Java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded Java.lang.Class from shared objects file]
[Loaded Java.lang.Cloneable from shared objects file]
[Loaded Java.lang.ClassLoader from shared objects file]
[Loaded Java.lang.System from shared objects file]
[Loaded Java.lang.Throwable from shared objects file]
.
.
.
[Loaded Java.security.BasicPermissionCollection from shared objects file]
[Loaded Java.security.Principal from shared objects file]
[Loaded Java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded Java.lang.Shutdown from shared objects file]
[Loaded Java.lang.Shutdown$Lock from shared objects file]
_

ご覧のとおり、アプリケーションクラス(HelloApp)に必要なJavaランタイムクラスが最初にロードされます。

Java 2プラットフォームのクラスローダー

Javaプログラミング言語は、アプリケーション開発者の生活を毎日楽にするために進化を続けています。これは、基本的なメカニズムの実装の詳細ではなくビジネスロジックに集中できるようにすることで、生活を簡素化するAPIを提供することによって行われますこれは、Javaプラットフォームの成熟度を反映するためにJ2SE 1.5をJ2SE 5.0に最近変更したことから明らかです。

JDK 1.2の時点で、JVMに組み込まれているbootstrapクラスローダーは、Javaランタイムのクラスをロードします。このクラスローダーはクラスのみをロードします。ブートクラスパスにあり、これらは信頼できるクラスであるため、検証プロセスは信頼できないクラスに関しては実行されません。bootstrapクラスローダーに加えて、JVMには拡張クラスローダーがあります。標準の拡張APIからクラスをロードする責任があり、アプリケーションクラスだけでなく一般的なクラスパスからクラスをロードするシステムクラスローダーもあります。

複数のクラスローダーがあるため、それらはルートがbootstrapクラスローダーです。各クラスローダーは親クラスローダーへの参照を持ちます。クラスローダーが要求されたときクラスをロードするために、アイテム自体をロードする前に親クラスローダーを参照し、親が順番に親を参照し、以下同様です。つまり、委任モデルが使用されます。

Java.lang.ClassLoaderクラス

_Java.lang.ClassLoader_は、JVMがクラスを動的にロードする方法を拡張する必要があるアプリケーションによってサブクラス化できる抽象クラスです。 _Java.lang.ClassLoader_(およびそのサブクラス)のコンストラクターを使用すると、新しいクラスローダーをインスタンス化するときに親を指定できます。親を明示的に指定しない場合、仮想マシンのシステムクラスローダーがデフォルトの親として割り当てられます。つまり、ClassLoaderクラスは委任モデルを使用してクラスとリソースを検索します。したがって、ClassLoaderの各インスタンスには親クラスローダーが関連付けられているため、クラスまたはリソースの検索が要求されると、クラスまたはリソース自体を検索する前にタスクが親クラスローダーに委任されます。 ClassLoaderのloadClass()メソッドは、クラスをロードするために呼び出されると、次のタスクを順番に実行します。

クラスがすでにロードされている場合、それを返します。それ以外の場合は、新しいクラスの検索を親クラスローダーに委任します。親クラスローダーがクラスを見つけられない場合、loadClass()findClass()メソッドを呼び出してクラスを見つけてロードします。 finalClass()メソッドは、親クラスローダーによってクラスが見つからなかった場合、現在のクラスローダーでクラスを検索します。


オリジナルの記事にはさらに多くの記事があり、独自のネットワーククラスローダーを実装する方法も示しています。この記事では、理由(および方法)に関する質問に答えています。 APIドキュメント も参照してください。

220
JRL

ほとんどのJava開発者は、クラスローダーを明示的に使用する必要はありません(JARにバンドルされている場合でも動作するようにリソースをロードする場合を除く)。

ClassLoaderは、大規模なシステムやサーバーアプリケーションで次のようなことを行うために使用されます。

  • システムをモジュール化し、実行時にモジュールをロード、アンロード、更新します
  • APIライブラリ(XMLパーサーなど)の異なるバージョンを並行して使用する
  • 同じJVM内で実行されているさまざまなアプリケーションを分離します(たとえば、静的変数を介して互いに干渉しないようにします)
45

質問は、「なぜこのClassLoaderクラスが存在する必要があるのか​​」です。

まあ、ほとんどの場合、うまくいかない場合は修正できます:-)。

アプリケーションを作成し、JARにコンパイルし、いくつかの追加のライブラリJARを含めることができる限り、クラスローダーについて知る必要はなく、動作するだけです。

それでも、クラスローダーとクラスローディングについて少し知っておくと、舞台裏で何が起こっているかをよりよく理解できます。例として、クラスがロードされると「静的初期化子」が実行されるため、実行されるタイミングを理解するには、クラスローダーがロードするタイミングを決定する方法を知る必要があります。

また、実際にどのように使用しますか?

単純なケースでは、それらは必要ありません。ただし、コードの実行元を明示的に制御して実行時にコードを動的に読み込む必要がある場合(たとえば、ネットワーク経由での読み込み、コンパイル時に利用できないプラグインの読み込みなど)、さらに行う必要があります。その後、例えば独自のクラスローダーを作成します。リンクについては他の回答をご覧ください。

27
sleske

ClassLoader in Javaは、Javaでクラスファイルをロードするために使用されるクラスです。Javaコードは、javacコンパイラとJVMは、クラスファイルに記述されたバイトコードを実行することにより、Javaプログラムを実行します。

ClassLoaderは、ファイルシステム、ネットワーク、またはその他のソースからクラスファイルをロードします。 Javaで使用される3つのデフォルトクラスローダーがあります。BootstrapExtensionおよびシステムまたはアプリケーションクラスローダー。

ClassLoader


How ClassLoader works

## JVMとClassLoaderの相互作用enter image description here

もっと@: how-classloader-works-in-Java.html

12
roottraveller

クラスローダーはJVMの機能コンポーネントであり、「。class」ファイルから、またはネットワーク経由でヒープのメソッドエリアにクラスデータをロードします。

JVMの不可欠な部分のように見えますが、終わりとしてJavaユーザーはなぜ心配する必要がありますか?ここに理由があります:

各クラスローダーには独自の名前空間があり、特定のクラスローダーによって呼び出されたクラスはその名前空間に入ります。

2つの異なるクラスローダーによって呼び出されるクラスは相互に可視性がないため、セキュリティが強化されます。

クラスローダーの親子の委任メカニズムにより、Java APIクラスが不正コードによってハッキングされることはありません。

詳細は こちら をご覧ください

4
bitan

ClassLoaderクラスが存在する理由を尋ねると、その理由は非常に単純です-実行時にクラスファイルを見つけてロードするクラスです

それを詳しく説明しましょう。

JVMでは、すべてのクラスはJava.lang.ClassLoaderのインスタンスによってロードされます。あなたがいつも新しいJVMを開始するときはいつもJava Java <classname>コマンドを起動するプログラム]、最初のステップはJava.lang.Objectのような適切な動作に必要なすべてのキークラスをメモリにロードすることですおよびその他のランタイムクラス(rt.jar)。

現在、ClassLoaderには実際には3つの部分があります。

  • BootstrapClassLoaderは、これらのクラスを使用可能にする、つまり、これらのクラスをメモリにロードする役割を果たします。

  • 次のタスクは、アプリケーションの適切な動作のために、外部ライブラリ/ JARをメモリにロードすることです。 ExtClassLoaderがこのタスクを担当します。このクラスローダーは、Java.ext.dirsパスに記載されているすべての.jarファイルをロードします。

  • 3番目の重要なクラスローダーはAppClassLoaderです。アプリケーションクラスローダーは、Java.class.pathシステムプロパティに記述されているクラスファイルのロードを担当します。

また、デフォルトのClassLoader実装をオーバーライドして、JVMを便利で興味深い方法でカスタマイズできるため、クラスファイルをシステムに取り込む方法を完全に再定義できることに注意することも重要です。

enter image description here

Java Class Loader の詳細を確認してください。

1
Johnny

クラスローダーは階層的です。クラスは、JVMですでに実行されているクラスで名前で参照されるため、JVMに導入されます。

最初のクラスはどのようにロードされましたか?
最初のクラスは、クラスで宣言されたstatic main()メソッドの助けを借りてロードされます。その後ロードされるすべてのクラスは、すでにロードされ実行されているクラスによってロードされます。

クラスローダーは名前空間を作成します。すべて[〜#〜] jvm [〜#〜]には、JVMに組み込まれているprimordial(またはブートストラップ)クラスローダー。それは一つのことであり、非原始クラスローダーを見ていきます。 JVMには、基本クラスローダーの代わりにユーザー定義のクラスローダーを使用できるようにするフックがあります。 JVMによって作成されたクラスローダーは次のとおりです。

Bootstrap(primordial)このクラスローダーは再ロードできません。 JDK内部クラス、Java。*パッケージをロードします(通常、rt.jarおよびi18n.jarをロードします)。 Extesionsこのクラスローダーは再ロードできません。 JDK拡張ディレクトリ(通常はJREのlib/ext)からjarファイルをロードします。システムこのクラスローダーは再ロードできません。システムクラスパスからクラスをロードします。

http://www.sbalasani.com/2015/01/Java-class-loaders.html

1