スレで質問する前に、同様の内容がこの FAQ に載っていないか調べましょう。
クラスの使いかたといった単純な質問は API ドキュメントを読んで自力で解決できないか試してみましょう。API ドキュメントは Java を使う上で絶対に必須です。
Q. javac コマンドを実行したときに、
コマンドまたはファイル名が違います
や
'javac' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。
などと表示されてコンパイルできません。
A. javac.exe への PATH が通っていません。
インストールガイド を良く読んで、javac.exe のあるディレクトリ(例: C:\jdk1.6.0_02\bin )のパスを環境変数 PATH に追加してください。その後、Windows98/ME の場合は OS を再起動、Windows2000/XP の場合はコマンドプロンプトを立ち上げなおしてください。設定したパスが正しければ、javacが使えるようになります。
それでも同じエラーが出る場合は、設定した値が間違っています。よく見直してください。
path,classpath も参照のこと。
Q. javac Hello.java でコンパイルはできるのですが、java Hello を実行しようとすると
Exception in thread "main" java.lang.NoClassDefFoundError: Hello
と表示されて実行できません。
A. カレントディレクトリ(.)がクラスパス(classpath)に含まれていません。コマンドプロンプトで
set CLASSPATH=%CLASSPATH%;.
と設定してください。最後の「;」と「.」を見落とさないように!
クラスパスとはなにか、path,classpath も参照のこと。
Q. 文字列を初期化するとき、
String str = new String("ほげ");
と
String str = "ほげ";
は実行時にどのような差があるのでしょうか? 前者には無駄な動きがあると聞いていますが、具体的にどのような動きになっているのでしょう?
A. 後者の場合は、 文字列リテラルはメモリ上のある領域にプールされたものが使い回されます。
Q. インタフェースの存在意義って何なんでしょうか?
A. インタフェースを implements するクラスでは、そのインタフェースで宣言されているメソッドをかならず具体的に実装しなければなりません。これにより、クラスの外部に対する動作を保証することができます。
例えば public void perform() というメソッドを宣言した Performable というインタフェースがあるとします。また、Performable を implements する2つのクラス Entertainer と Athlete があるとします。このとき、Entertainer と Athlete は絶対に perform() というメソッドを持つことが保証されますが、perform() の具体的な動作は実装クラスで定義されるので、同じ perform() というメソッドで Entertainer と Athlete のそれぞれに見合った異なる動作をすることができます。
インタフェースは変数の型名としても用いることができるので、
Performable hatayouku = new Entertainer(); Performable ichiro = new Athlete();
とすれば、perform() というメソッドに関して統一的に扱うことができるのです。
hatayouku.perform(); // Entertainer としての動作 ichiro.perform(); // Athlete としての動作
つまり、インタフェースとはオブジェクト指向におけるポリモルフィズム(polymorphism)の利用の実例といえるでしょう。
Q. 値渡しと参照渡しがよくわかりません!
A. 引数としてメソッド(関数)に渡された変数がそのメソッド内で扱われる方式には、値渡しと参照渡しの2通りがあります。値渡しとは、メソッドに渡される際に変数の内容がコピーされ、メソッド内部ではコピーされた値を用いる方式です。一方、参照渡しとは、メソッドには変数の参照がそのまま渡され、メソッド内で直接その変数を処理する方式です。
Java の場合は、プリミティブ型(int, boolean, ...)・オブジェクト型(String, Integer, ...)に関わらず、すべて「値渡し」です。ただし、渡されるものはプリミティブ型の場合は値そのもののコピー、オブジェクト型の場合は参照値のコピーになります。また、「参照値の値渡し」のことを広義に「参照渡し」と呼ぶ人もいますが、参照値の値渡しと参照渡しでは根本的な違いがあるので、きちんと理解することが大事です。
たとえば、
と、考えてみてください。これをふまえた上で、例として次のようなメソッドを考えてみましょう。
static void swap(int a, int b) { int c = a; a = b; b = c; }
static void methodA(Integer a) { int b = a.intValue() * 2; a = new Integer(b); }
static void methodB(StringBuffer buf) { buf.append("unko"); }
int はプリミティブ型で、メソッドには値のコピーを渡しますので、いくらメソッド内で変数に変更を加えても呼び出し元には影響しません。コピーしたファイルをいくら書き換えようと、元のファイルには影響がありませんね。
int a = 1; int b = 2; swap(a, b); System.out.println("a = " + a); // 「a = 1」と表示される System.out.println("b = " + b); // 「b = 2」と表示される
Integerはオブジェクト型ですが、methodA では 参照値のコピーである a に対し、新たに別の参照値を与えています。つまり、ファイラのアドレスバーに別のファイルのアドレスを入れてしまっているだけです。これもまた、元のファイルには影響がありません。
Integer hoge = new Integer(5); methodA(hoge); System.out.println("hoge = " + hoge); // 「hoge = 5」と表示される
ここでmethodAを呼び出すと結果が10になるような言語もあります。つまりmethodAのパラメタaは、引数hogeを参照しており、aを置き換えるとhogeも変わってしまうような言語があるわけです。pascalやVisual Basicにはそういう機能があります。この機能を「参照渡し」といいます。
Javaには値渡ししかありませんので、上記例では必ず5と表示されます。methodAの中のaを置き換えても、もとのhogeのコピーに過ぎませんのでhogeには影響しません。
methodB はどうでしょう。これは、アドレスバーで指し示しているファイルそのものに対して操作を行う、つまり呼び出し元で見ているのと同じオブジェクトに対して操作を行っているわけですから、呼び出し元にも影響があります。
StringBuffer sb = new StringBuffer(); methodB(sb); System.out.println("sb = " + sb.toString()); // 「sb = unko」と表示される
sbという参照値がmethodBのパラメタbufにコピーされます(つまり参照値が値渡しされます)。sbとbufは全く異なるものですが、指している先のオブジェクトは同じです。buf.append()によってオブジェクト内容が変われば、当然sb.toString()の内容に反映されるわけです。
この違いをしっかりと理解しましょう。Smith君。
Q. printfを使うと
シンボルを解決できません。 シンボル: メソッド printf (java.lang.String,double) 場所 : java.io.PrintStream の クラス
などと表示されて使えません。
A. JDKを最新版にしましょう。
System.out.printfはJ2SE 5.0から導入されました。 なので、それより前のバージョンでは使えません。 System.out.printfを使いたい場合はJ2SE 5.0以上を使いましょう
検索エンジンでSDKを検索すると、J2SE v 1.4.2_16 SDKがトップに来てる上に、SUNのホームページがこれまた分かりにくいという二重の罠が張り巡らされているので気を付けてくださいwwww
http://java.sun.com/javase/downloads/index.jsp のリンク先から、画面右にある日本語版をクリックするのが最新版を手に入れるのに一番確実な方法だと思います。(一般的なパッケージは一番上のJDKです。説明書的なドキュメントは上から六番目のJava SE 〜 ドキュメントという奴です。)
Q. 質問したら「Javadoc読め」としか答えてもらえなかったんですけど、Javadocって何ですか?
A.「読め」と言われた場合は通常、「Javadoc形式のAPIリファレンス」のことです。
大抵はJavaSEのAPIリファレンスのことですが、質問が特定のライブラリに関するものであった場合などは、そのライブラリのAPIリファレンスを指すことになるでしょう。
なお、「Javadoc読め」だけの回答は、「APIリファレンスをちゃんと読んでれば、質問するまでもなく解決するような内容なんだけどな」という意味でもあります。自分自身の知識になることなので、質問する前にまずはめんどくさがらずにAPIリファレンスを読んでみましょう。
/* ツールとしてのjavadocについてはSunのマニュアル読んでください。 */