- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!!!技術的雑談-Javaコンパイラ・ソースの基礎
!!環境
*JDK1.4、1.5どっちも。
*プラットフォーム問わず
!!目的
何でJavaのソースはあんなにディレクトリがたくさんあるのか理解する
!!内容
Javaではソースについて以下の3つのお約束があります。
+ ソースファイルは「*.java」、コンパイルされたファイル(classファイル)は「*.class」
+ 基本的に、ソースのファイル名と中のClass名は同じにする。
+ ソースの置いてあるディレクトリ階層はClassのPackage階層に合わせる
(ルール3は別に守らなくてもコンパイルは可能ですが、著しくめんどくさくなります。)
ソース、クラス(コンパイルした後の生成物)はpackage(C++で言うところのNamespace)ごとにディレクトリが掘られるのが普通です。
例えば、以下のようなソース構成だったとします。
[ディレクトリ]
./
/src
/com
/hoge
/fuga
TestClass.java
/mugyo
Sub.java
/bin
[TestClass.java]
package com.hoge.fuga;
public class TestClass {
}
[Sub.java]
package com.hoge.mugyo;
// SubはTestClassを参照している
public class Sub extends com.hoge.fuga.TestClass {
}
この状態で「TestClass」に対して下記のようにjavacを実行すると、
(./ ディレクトリにいる)
javac -sourcepath ./src -d ./bin ./src/com/hoge/fuga/TestClass.java
[ディレクトリ]
./
/src
/com
/hoge
/fuga
TestClass.java
/mugyo
Sub.java
/bin
/com
/hoge
/fuga
TestClass.class
というファイルが作られます。
ディレクトリはコンパイラによって勝手に作られます。
javacコンパイラはコンパイルに必要な依存Classを以下の方法で探してきます。
- 指定されているソースツリー(-sourcepathで示されるディレクトリ以下)
- javacに-classpathで指定されているjar、もしくはディレクトリ
- JDK標準ライブラリー (普通は${JAVA_HOME}/jre/lib以下のjar)
先程生成されたTestClass.classを消して、
javac -sourcepath ./src -d ./bin ./src/com/hoge/mugyo/Sub.java
を実行しても、
[ディレクトリ]
./
/src
/com
/hoge
/fuga
TestClass.java
/mugyo
Sub.java
/bin
/com
/hoge
/fuga
TestClass.class
/mugyo
Sub.class
と、Sub.classだけでなくTestClass.classも作られます。
これは -sourcepath ./srcが指定されているのでコンパイラが自動的にpackage構造を理解して必要なClassを探してくる為です。
その過程でコンパイラはTestClassも依存性があると判断して勝手にコンパイルします。
また、./src/com/hoge/fuga/TestClass.javaがない状態でも、./bin/com/hoge/fuga/TestClass.classがあるなら、
javac -sourcepath ./src -d ./bin -classpath ./bin com/hoge/mugyo/Sub.java
と実行する事により、コンパイラがSub.javaが依存するコンパイル済みのTestClass.classを探してきて、コンパイルを完了します。
上記からもわかるように、-sourcepath、-classpathはその下にあるpackage階層をディレクトリ階層によって理解しますので、ソースもclassもpackageの階層どおりに掘っておく事が望ましいです。
実際は、1つ1つ指定すればソースは階層を無視した状態(例えば、全てのpackageのソースを1つのディレクトリにフラットに置くとか)でもコンパイルは通ります。
しかし、Class毎の依存関係をコンパイラが自動的に判断できない為、ものすごく面倒になります。
(人間が人力で依存関係を解析して、-classpathに与えてやる必要があります。)
!!履歴
2005/7/15 -- 初版発行
[[技術的雑談]]に戻る
!!突っ込み
{{comment}}
[[技術的雑談]]に戻る
{{trackback}}
[[技術的雑談]]へ戻る