• ベストアンサー

Java「デフォルトのパッケージ」の意味が分かりません。

 Java「デフォルトのパッケージ」の意味が分かりません。 http://takeoba.cool.ne.jp/java/packageDeclaration.htm に パッケージ宣言しないプログラムは、デフォルトのパッケージに割り当てられます。 と書かれているのですが「デフォルトのパッケージ」の意味が分かりません。  Googleで「Java デフォルトのパッケージ」を検索してもヒットする件数は多いのですが「デフォルトのパッケージ」の意味そのものに触れたものがなかなか見つかりません。  Javaに詳しい方、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#49664
noname#49664
回答No.5

なんというか、パッケージを「クラスファイルの保存場所」と思われてしまうとまずいので、微妙に追加を。 まず、パッケージというのは何のためのものか、それをご理解ください。これは、クラスファイルの保存場所に関するものではありません。パッケージというのは、クラスに名前空間を与え管理するためのものです。わかりやすくいえば、ファイルをフォルダで分類して整理できるのと同じように、すべてのクラスを、場所を指定して管理できるようにするための仕組みのことです。 Javaでは、クラス名を記述してプログラムを動かしますね? では、同じクラスが複数あったらどうなるでしょうか? Javaはそれらを区別することができなくなります。が、実質問題として、さまざまな人間がすべて異なる名前でクラスを定義するとは思えません。そこで、クラスを保存する場所を階層的に指定し、「このクラスは、jp.hoge.hogeという場所にあるクラスですよ」ということを示して扱えるようにしたわけです。これが「パッケージ」です。 実際、標準で付いてくるクラスを見ると、java.awt.Buttonというように、パッケージの中に収めてあることがわかります。が、こうなると今度は「ちょっとプログラムを試しに動かしたいのに、わざわざ他とは重複しないパッケージを定義して動かさないといけないのは面倒だ」ということになります。そこで、「それじゃあ、何もパッケージを指定しないで作ったクラスは、仮にデフォルトパッケージというパッケージを用意して、その中にあるという扱いにしよう」ということで考えられたのがデフォルトパッケージです。 パッケージを指定したクラスは、(アーカイブ化していなければ)それぞれの階層がフォルダとして用意された形で保存されます。例えば、jp.hoge.Testならば、「jp」フォルダ内に「hoge」フォルダがあり、その中に「Test.class」が保存されます。が、パッケージ指定していなければ、(階層がありませんから)フォルダなどなく、その場に保存されます。classファイルのある場所が、デフォルトパッケージのクラスが保管されている場所と判断されるわけです。が!「保存されているフォルダがパッケージのことだ」とは思わないでください。これは、ただの「現象」です。たまたま、現在のJavaはそういう形でファイルを保存するようになっている、というだけのことです。パッケージは、あくまで「プログラム上に用意される空間」です。ファイルの保管場所のことではありません。 デフォルトパッケージというものが用意されている理由は、「Javaのクラスは、必ずどこかのパッケージに置かれなければならない」からです。パッケージのないクラスは存在できません。なぜなら、Javaの言語仕様に、パッケージの存在がかかわっているからです。例えば、クラスを定義するのに「public」をつけますが、これが付いていないと「同一パッケージ内についてpublic」と扱われます。つまり、「パッケージ内のクラスとパッケージ外のクラス」で利用が異なるような仕様が文法に既に用意されているのです。このため、必ずクラスはどこかのパッケージに属さなければなりません。それで、まったくパッケージを指定していないものも、デフォルトパッケージというパッケージに所属するという形で扱われるようになっているのです。

noname#179638
質問者

補足

 Kyon2_PaPaさま、こちらの質問でもご回答いただきありがとうございました! >「保存されているフォルダがパッケージのことだ」とは思わないでください。これは、ただの「現象」です。 なるほど! これはJavaの入門書を読んだだけではなかなか分らないですね~ import文を書くとき、 import文を書いたファイルをコンパイルするとき カレントディレクトリまたは-dオプションのフォルダからの相対パスでimport文を書かなければならないのでしょうか? この場合、javax.swing.*;などの標準ライブラリは相対パスにならないですよね? Sun製のrt.jarの。 自作のクラスの場合だけカレントディレクトリまたは-dオプションのフォルダからの相対パスでimport文を書かなければならないのでしょうか? Sunの標準ライブラリだけ例外? ソースコードと同じフォルダにあるclassファイルの型のインスタンスを生成する場合、import文や完全名は必要なくて単にクラス名だけでインスタンスを生成できるのですか? カレントディレクトリにあるソースコードをコンパイル時に-dオプションをつけるとカレントディレクトリではなく-dオプションで指定したフォルダ(このフォルダをAとします)にclassファイルができるのですか? -dオプションをつけずに-classpathで指定したフォルダのソースコードをコンパイルすると-classpathで指定したフォルダではなくカレントディレクトリ(このフォルダもAとします)にclassファイルができるのですか? そしてそれぞれソースコードにパッケージ宣言をつけてコンパイルするとAからのパッケージ宣言をした相対位置のフォルダにclassファイルができるのですか?  すいません。よろしくお願いいたします。

その他の回答 (7)

  • davosuke
  • ベストアンサー率61% (34/55)
回答No.8

>参照、または継承する自作のソースコードをコンパイルするとき >他人が作ったソースコードの分からないclassファイル、 >jarファイルは参照、または継承する自作のソースコードの >classファイルの吐き出し先に他人が作ったソースコードの >分からないclassファイル、jarファイルがコピーされるのですか? デフォルトパッケージ直下から固められたjarファイルや、他人が作ったソースコードの分からないclassファイルにパッケージ文ない場合 クラスパスで指定した直下に置けば自作のソースコードを コンパイルの問題はありませんが、 他人が作ったソースコードの分からないclassファイルが パッケージ文ある場合は、正しく、クラスパスからのパッケージを作成しないと参照された、自作のソースコードはコンパイルエラーになります。

noname#179638
質問者

お礼

 みなさま、ありがとうございました!! とても参考になりました!!

  • davosuke
  • ベストアンサー率61% (34/55)
回答No.7

>これは >参照しているクラス hensuu = new 参照しているクラス(); >とか >と解釈してよろしいのですよね? クラス参照するということは、インスタンスを生成するときもそうですが、クラスメソッド(静的メソッド)やクラス変数(スタティック変数)をコールするときも同じです。 >カレントディレクトリにあるソースコードを >コンパイル時に-dオプションをつけると >カレントディレクトリではなく-dオプションで >指定したフォルダ(このフォルダをAとします)に >classファイルができるのですか? はい、そうです。 >-dオプションをつけずに-classpathで指定したフォルダの >ソースコードをコンパイルすると-classpathで指定した >フォルダではなくカレントディレクトリ >(このフォルダもAとします)にclassファイルができるのですか? はい、そうです。 >そしてそれぞれソースコードにパッケージ宣言をつけて >コンパイルするとAからのパッケージ宣言をした相対位置の >フォルダにclassファイルができるのですか? はい、そうです。

noname#179638
質問者

補足

 他人が作ったソースコードの分からないclassファイル、jarファイルを参照、または継承する場合「クラスパス中に置いてください」とか言われることがあります。 参照、または継承する自作のソースコードをコンパイルするとき 他人が作ったソースコードの分からないclassファイル、jarファイルは 参照、または継承する自作のソースコードのclassファイルの吐き出し先(自作のソースコードがimoprt文を使ってる場合(つまり他人が作ったソースコードの分からないclassファイル、jarファイルがパッケージ宣言している場合)は参照、または継承する自作のソースコードのclassファイルの吐き出し先からのimoprt文の相対位置)に 他人が作ったソースコードの分からないclassファイル、jarファイルがコピーされるのですか?

  • hofchan
  • ベストアンサー率62% (17/27)
回答No.6

さらに深く迷われているような気がしますが javac -d は javac -help でもわかるように、class ファイルの吐き出し場所を指定するだけで パッケージに影響しません、パッケージに何も宣言しなければ どこのディレクトリでコンパイルしてもデフォルトのパッケージなのです >この場合、hoge2がデフォルトパッケージ。 ディレクトリ=パッケージ ではありません、コードの上での扱い方の問題です

noname#179638
質問者

補足

 hofchanさま、ご回答ありがとうございました!  パッケージ宣言の有無によってclassファイルの吐き出し場所はいろいろ変わるけど パッケージ宣言の有無にかかわらず classファイルの吐き出し場所がデフォルトのパッケージなのですか? import文はimport文を書いたソースコードのコンパイル時のclassファイルの吐き出し場所からの相対パスでクラスなりパッケージなりを指定しなければならないのですか? Sun製の標準ライブラリは別として。  よろしくお願いいたします。

  • hofchan
  • ベストアンサー率62% (17/27)
回答No.4

言葉たらずで申し訳ありませんでした、気になったので横槍かと 思いましたが少し難しく考えられてるようなので mkdir hoge1 hoge2 cd hoge1 として、ここに(hoge1ディレクトリの中)パッケージの無い public class hoge1{ public void foo(){ System.out.println("Hello"); } } hoge1.javaを作ります、次に cd ../hoge2 ここに(hoge2 ディレクトリの中) public class hoge2{ public static void main(String args[]){ hoge1 h = new hoge1();  h.foo(); } } これをhoge2.javaとした時 cd hoge1 javac hoge1.java これは問題無くコンパイル出来ます 今度は cd ../hoge2 javac hoge2.java これは当然通りません、しかし最初のコンパイルで出来た hoge1.class と同じディレクトリに hoge2.java を置くことで import 宣言も何もなしでコンパイル出来ます、2つとも同じ デフォルトのパッケージに含まれています #CLASSPATHに「.」がいるのかな? 当然 davosuke様が言うように、最初のコンパイルで javac -d ../hoge2 hoge1.java でもかまいません、デフォルトのパッケージ同士は同じパッケージ と簡単に考えてもいいと思います

noname#179638
質問者

補足

 コンストラクタ側のクラスのコンパイル時に -dオプションでインスタンス生成側のクラスがあるフォルダを指定するのですね! この場合、hoge2がデフォルトパッケージ。 もしくはインスタンス生成側のクラスをコンストラクタ側のクラスと同じフォルダに移動orコピーしないといけないのですね! この場合、hoge1がデフォルトパッケージ。 こんな感じでしょうか?

  • davosuke
  • ベストアンサー率61% (34/55)
回答No.3

>デフォルトパッケージはカレントディレクトリのC:\aaaではなく>a.javaが入っているC:\bbbになるのでしょうか? それは、違います。C:\aaaがデフォルトパッケージです。 javacコマンド実行時にclaspathを指定しても、 コンパイル時にはコンパイル対象javaファイルが参照している classがclasspath内に存在しないとコンパイルが通りません。 よって、-dオプションにて指定していない場合、 カレントディレクトリのC:\aaaになります。

noname#179638
質問者

補足

>コンパイル対象javaファイルが参照しているclass これは 参照しているクラス hensuu = new 参照しているクラス(); とか と解釈してよろしいのですよね?

  • davosuke
  • ベストアンサー率61% (34/55)
回答No.2

javaファイルをコンパイルし、classファイルを作成する javacコマンドはご存知でしょうか?? ご存知なら、以下のa.java,b.java,c.javaをコンパイルしてみてください。 =============== クラスA(a.java) ============== package a public class A{ } =============== クラスB(b.java) ============== package a.b public class B{ } =============== クラスC(c.java) ============== //コメントパッケージなし //package a.b public class C{ } 【実行例】 DOSプロンプトより実行 javac a.java javac b.java javac c.java そしたら、 DOSプロンプトより実行したカレントディレクトリに 配下に c.class a(フォルダ)\a.class a(フォルダ)\b(フォルダ)\b.class が作成されます。 このようなc.classのようなものをデフォルトパッケージのクラス といいます。 コンパイル時作成されるパッケージなのですが、何も指定していなければ、どこに作成すればよいか、JAVAコンパイラはわからないので、 デフォルトパッケージを指定します。 結果、デフォルトパッケージとは、 クラスパッケージを作成する基点です。 サンプル例で言いますと、 DOSプロンプトより実行したカレントディレクトリ になります。 ちなみに javac -d ディレクトリパス -d オプションをつけると、 ディレクトリパスがデフォルトパッケージになります。 -dオプションを省略すると、DOSプロンプトより実行したカレントディレクトリになります。

noname#179638
質問者

補足

 davosukeさまご回答ありがとうございました! javacコマンド、存じ上げております。 最近は、統合開発環境の人も多いのでjavacをご存じでない方も多いのでしょうね…  本題に入りますがたとえば(davosukeさまの回答のサンプルとは直接関係なく)パッケージ宣言の無いa.javaがカレントディレクトリ以外のC:\bbbにあったとして javacのディレクトリに環境変数PATH=を設定済みで コマンドプロンプトから C:\>cd C:\aaa C:\aaa>javac -classpath C:\bbb a.java と入力したとします。 この場合、デフォルトパッケージはカレントディレクトリのC:\aaaではなくa.javaが入っているC:\bbbになるのでしょうか?  よろしくお願いいたします。

  • hofchan
  • ベストアンサー率62% (17/27)
回答No.1

まずパッケージの中に、複数のクラスを含めることが出来ます そのパッケージのクラスからは、同じパッケージのクラスを呼び出すことが 出来ます 宣言の無いものを簡単に言えば、名前の無いパッケージと考えてください パッケージ宣言の無い class hoge{ を public でなくても呼び出せるのです

関連するQ&A