4

私はEclipseでいくつかのJavaコードに取り組んでいます。Adderコードは、Eclipseではパッケージに含まれていると呼ばれる単一のクラスに含まれていますorg.processing。クラスファイルの最初のものは行です

package org.processing

Q1) この行は正確に何をしているのですか?なぜそこにあるのか、それはどのような役割なのか。

コードはEclipseで正常に実行されますが、ワークスペースに移動すると、のsrc/org/processing/フォルダーに移動srcし、javac Adder.classを使用して実行しようとするとjava Adder、次のエラーが発生します。

java.lang.NoClassDefFoundError: Adder (wrong name: org/processing/Adder)

一方、srcからコンパイルする場合は

javac org/processing/Adder.java

srcを使用して実行することはできますjava org.processing.Adderが、処理ディレクトリ内からは実行できません。

Q2) これは、コンパイルが常にディレクトリ構造に関連していることを意味しますか?

最後に、 package org.processing最初から行を削除すると、ファイルのディレクトリ.class内からコンパイルして実行できるファイルになります。.class

Q3) なんでこんな感じなの?コード開発のためにディレクトリ構造を適用することは完全に理解できますが、バイトコードに入ると、これは少しやり過ぎのように見えます。これは、(どうやら)1つのダイレクタ(src)からのバイトコードしか実行できないためjava org.processing.Adderです。さて、私はここでポイントを逃していると確信しているので、誰かがそれが何であるかを指摘することができれば、それは素晴らしいことです。

4

4 に答える 4

2

コンパイラは、コンパイル時に関連するソースコードファイルを見つけることができなければなりません。これが、パッケージとディレクトリ構造がソースコードについて一致している必要がある理由です。同様に、JVMは参照される.classファイルを見つけることができなければなりません。したがって、実行時に同じディレクトリ構造が必要です。それ以上に複雑ではありません。

于 2012-09-02T03:47:00.060 に答える
2

Q1)ここでの問題は、パッケージ階層を表すフォルダーに入ったら、それを作業ディレクトリとして設定することです。org /processing/Adderの内部でパスorg/processing/ Adderを探します(基本的には、ルートからorg /processing / Adder / org /processing / Adderを探します)。ルートからフルパスで呼び出す必要があります。パッケージの目的はA:関連するクラスをグループに編成することです。そしてB:Aと一緒に、パッケージFoo.barのクラスは、他のパッケージのプライベートクラスを表示できません。これらは、そのパッケージの内部クラスのようなものであり、それらが含まれているパッケージのみがそれらを使用できます。

Q2)はい

Q3)パスは、JVMがクラスファイル(それぞれにバイトコードを含む)が正確にどこにあるかを知るための基本構造として使用されます。呼び出し元を変更すると、基本的にJVMの場所を変更してクラスファイルを検索しようとしますが、実際の場所は変更されていません。

于 2012-09-02T03:47:12.633 に答える
1

Q1の場合:パッケージ宣言を使用すると、クラスが同じ名前の別のクラスと間違えられないことが保証されます。これが、ほとんどのプログラマーが自社の名前をパッケージに入れる理由です。競合が発生する可能性はほとんどありません。

Q2の場合:パッケージ構造とディレクトリ構造の間には1対1の対応があります。要するに、ディレクトリとパッケージは同じでなければならないということです。ただし、パッケージは通常srcというフォルダの下にルートされています。

Q3の場合:コンパイルされると、クラスファイルはおそらくjarファイルの適切なフォルダーに配置されます。antまたはmavenタスクはjarファイルをビルドするので、antタスクを最初にセットアップする以外に、実際にそれを気にする必要はありません。

于 2012-09-02T03:48:39.947 に答える
1

簡単な答え-パッケージは、プロジェクト構造を適切に整理し、名前を再利用できるようにし(2つのクラスに名前を付けてみてください)、非常に大規模なプロジェクトAccountの一般的な規則です。それらはフォルダ構造にすぎませんが、なぜそれらが使用されるのかは初心者をかなりひどく燃やす可能性があります。おかしなことに、プロジェクトが5クラス未満の場合、おそらくそれは必要ありません。


正確には、この行は何をしているのですか?なぜそこにあるのか、それはどのような役割なのか。

この線

package org.processing

このクラスファイルが/org/processingというフォルダにあることをJavaに伝えています。 これにより、org.processing.Processorここで完全に定義されたクラスを作成できます。また、別のフォルダー(たとえば、/ org / account /processing)に、完全に定義されたクラスを作成できますorg.account.processing.Processor。はい、どちらも同じ名前を使用していますが、衝突することはありません。異なるパッケージに含まれています。同じクラスでそれらを使用することにした場合は、importステートメントまたは完全修飾オブジェクト名のいずれかを使用して、どちらを使用するかを明示する必要があります。

これは、コンパイルが常にディレクトリ構造に関連していることを意味しますか?

はい。Javaおよび他のほとんどの言語には、クラスパス と呼ばれる概念があります。このクラスパス上のすべてのものをコンパイルして実行できます。デフォルトでは、現在のディレクトリがコンパイルと実行のためにクラスパス上にあります。クラスパスに他のファイルを配置するには、コンパイルに対して別のコマンドライン呼び出しを使用する必要があります。

javac -sourcepath /path/to/source MainClass.java

...これにより、ソースパス内のすべてが現在のディレクトリにコンパイルされ、パッケージステートメントで指定されたフォルダ構造にきちんと整理されます。

それらを実行するには、すでに確立しているように、コンパイルされたソースをクラスパスに含めてから、完全修飾オブジェクト名を使用して実行する必要があります。

java -cp /path/to/source org.main.MainClass

なぜこれがすべてのようになっているのですか?

前に述べたように、これは非常に大規模なプロジェクト、またはAndroidなど、他の多くのクラスと需要構造/組織を含むプロジェクトに主に役立ちます。それはいくつかのことをします:

  • ソースを見つけやすい構造に整理します。いたるところにオブジェクトが散らばっていません。
  • オブジェクトの範囲を明確に保ちます。という名前のパッケージがある場合org.music.db、データベースと永続性を処理するオブジェクトをいじっていることは明らかです。という名前のパッケージがある場合org.music.gui、このパッケージがプレゼンテーション側を扱っていることは明らかです。これは、新しい機能を作成したり、既存の機能を更新/リファクタリングしたりする場合に役立ちます。それが何をするかは覚えていますが、その名前を正確に思い出すことはできません。
  • これにより、同じ名前のオブジェクトを作成できます。 そこには複数のタイプがMapあり、それを取り込むプロジェクトを使用している場合は、インポートまたは完全修飾オブジェクト名のいずれかを使用して、どちらを取得するかを指定できるようにする必要があります。 Map
于 2012-09-02T03:56:12.650 に答える