!!!技術的雑談-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}} [[技術的雑談]]へ戻る