Java/Hello world
「Hello world」について[編集]
本ページでは、次のことを説明していきます。
- ソースコードの書き方
- コンパイルの仕方
- コンパイルしたプログラムの実行の仕方
では、いよいよJavaのプログラミングを始めましょう。 最初につくるプログラムは「Hello world(ハローワールド)」です。
「Hello world」とは、コマンドプロンプト(ターミナル)の画面上に「Hello, world.」という文字を表示するだけのシンプルなプログラムです。文字を表示するだけですから、プログラム自体に実用的な意味はありません。とりあえず気楽に始めてみましょう。
プログラムを記述する[編集]
まず、お好みのテキストエディタを使って下記のようなプログラムを入力し、保存します。
下記コードの場合、ファイル名は「Main.java
」にする必要があります(Javaの場合ファイル名はクラス名と同一である必要がある)。
- Main.java
public class Main { public static void main(String[] args){ System.out.println("Hello, world."); } }
- 参考
- ソースファイルを保存する場所は、原則的にどこでも構いません。しかし、コマンドプロンプト(ターミナル)からアクセスしやすい場所に保存しておくと、後の作業が楽になります。なので、
~/java.src/
に、Windowsならば %USERPROFILE%\java.src\
など憶えやすい場所に保存するようにしておくと便利です。Javaはコンパイル時にクラスファイルという中間ファイルを作成します。
C++(開発当時の仮称:C with Classes)が開発された1980年代あたりからICT業界では class という用語が色々な意味で使われますが、Javaでいうclass という用語には。クラスファイルという意味もあるので、気をつけください( C++の class と、Javaのclass とは意味するところが異なります)。
上記コードの場合、public class Main
とクラスファイル名を「Main」だと指定しています。
プログラムを実行する[編集]
Javaは、BASICやJavaScriptのようなインタープリターと同じ様にソースコードを即時に実行する事もでき、 さらにコンパイルして、どこのOSでも動かせられる中間ファイルを作成する事も可能です。
Javaでいう「コンパイル」とは、この中間ファイルを作ることです。「.exe」のようなWindowsに依存した実行ファイルを作るワケではありません。
Linux の場合、OSの種類やインストール状況によってはインタプリタとしては動作しない場合がありますので、コンパイルして使うことをお勧めします。
インタプリタで即時に実行する場合[編集]
Windowsの場合、
java Main.java
のコマンドで可能です。インタプリタ利用の場合、javaの末尾に「c」がついていない事に注目してください。
つまり書式は
java ファイル名
です。
実行してみて
Hello, world.
と表示されたら成功です。
プログラムをコンパイルする場合[編集]
- 要点
javac Main.java java Main
と入力。
この意味は
javac ソースファイル名 java クラスファイル名
である。詳しくは後述。
- 解説
コンパイルして実行したい場合、コマンドプロンプト(ターミナル)で、上記のファイルを保存したディレクトリに移動し、次のコマンドを実行します。このコマンドは、上記のプログラムをコンパイルするためのものです。最初の「H」は大文字なので気をつけてください。
javac Main.java
javacのように末尾に「c」がある事に注目してください。
コマンド実行後に何も表示されなければ、コンパイルが成功したことを意味します。コンパイルの生成物として、今回の場合、カレントディレクトリにMain.class
というファイルができているはずです。
この、「.class
」という拡張子を持つファイルをクラスファイルと呼びます。クラスファイルは、実行ファイルではありません。Javaのソースコードをバイトコードと呼ばれる形式に変換したものです。これを実行するには、後述するjava
コマンドを使う必要があります。
ディレクトリを移動するには、cd
コマンドを使います。もし、Windowsをお使いでMain.java
をC:\src
ディレクトリに保存しているなら、まず
> cd C:\src
を実行してから(先頭の「>
」はプロンプトを意味しています。入力はしません)、上記のjavac
コマンドを実行します。Main.class
が作成されたかどうかは、
> dir
を実行して確認することができます。
なお、こうしたコマンドプロンプトのコマンドの使い方については、MS-DOS/PC DOS入門で知ることができます。
- 参考
:もし、クラスファイルが生成されず、何らかのエラーメッセージが表示された場合(すなわち、コンパイルエラーになった場合)は、入力したプログラムに間違いがないかどうかを確認します。コンパイルエラーに対するデバッグは、基本的に表示されたエラーメッセージを手がかりに行いますが、慣れないうちは、メッセージの内容が必ずしも理解しやすいとは限りません。デバッグする際の主な確認ポイントには、たとえば次のようなものがありますので、参考にしてください。
- 全角文字を使っていないかどうか。上記のプログラムは、すべて半角文字で入力してください。
- ファイル名が「
Main.java
」になっているかどうか。「Main.java.txt
」などになっていないかどうか。 - 大文字と小文字を正確に使い分けているかどうか。
- プログラミング特有の記号類は正しく入力しているか。セミコロン(
;
)とコロン(:
)を間違えていないかどうか、中括弧({ }
)、角括弧([ ]
)は正しく入力されているか。
プログラムを実行する[編集]
最後にプログラムを実行します。次のようにコマンドを実行します。
java Main
「Hello, world.」と表示されれば成功です。うまくいきましたか?
コンパイルは通るのに、実行しようとするとjava.lang.NoClassDefFoundError
が発生してしまうことがあります。
この原因はクラスパスの指定にあるかもしれません。
Windowsを使っている場合にこの現象が起こる可能性が高いので、ここではWindowsを前提に解説します。
(Linux、UNIXでよく使われるbash, cshシェルについても付随的に説明します。)
まず、コマンドプロンプトから
> echo %CLASSPATH%
(csh/bashの場合)
> echo $CLASSPATH
を実行してみてください。 何らかのパスが表示された場合は、おそらくクラスパスが原因です。
対処する方法は3つあります。
1) まず最初の方法は、クラスパスの指定を消してしまう方法です。
コマンドプロンプトから、
> set CLASSPATH=
(cshの場合)
> setenv CLASSPATH
(bashの場合)
> export CLASSPATH=
と入力します。これで、クラスパスの設定が消えますから、java
コマンドがカレントにあるクラスを見つけることができるようになります。ただし、次回コマンドプロンプトを立ち上げた際には、また同じことを行う必要があります(つまり、上記の指定は、あくまで現在開いているコマンドプロンプトのウィンドウにだけ適用されるものなのです。次回以降に立ち上げたウィンドウには適用されません)。
2) 次の方法は、java
コマンドのオプションでクラスパスを指定する方法です。
> java Main
の代わりに
> java -cp . Main
と入力します。上記のように「-cp」(または「-classpath
」)というオプションの引数に「.」(つまり、カレントディレクトリのこと)が設定すると、クラスパスに「.」が設定された状態でjava
コマンドが実行されます。これでjava
コマンドがクラスを見つけることができるようになります。
このように、-cp
オプションで指定した場合、指定されたクラスパスはそのコマンドにのみ適用されます。次回以降に入力されるコマンドには適用されません。
3) 最後の方法は、CLASSPATHの設定に「.」を追加する方法です。
(bashの場合)
> export CLASSPATH=.:$CLASSPATH
(TODO)
上記のように、Javaプログラムを実行するには、java
コマンドを使う必要があります。
java
コマンドの引数には、クラス名(この場合は「Main
」)を指定します。java
コマンドは、指定されたクラス名に対応するクラスファイルを読み込み、それをJIT(Just In Time)コンパイラでコンパイルして実行します。つまり、ここでバイトコードは実行形式に変換され、実行できるようになるのです。
Hello worldの解読[編集]
Hello worldの意味を見ていきましょう。
第1行目[編集]
まず最初の行を見てみましょう。
public class Main {
第1行目は、クラスというものを宣言している部分です。
クラスというのはJavaプログラムの基本単位です。「Main」はごく単純なサンプルなので、クラスはこれ1つしかありませんが、ふつうは複数作成し、相互にやりとりさせてプログラムを作ります。
「クラスとはJavaプログラムの基本単位」という説明をしましたが、この説明だけではもちろんクラスが何であるかを説明できたことにはなりません。読者の中には「クラスが何かよくわからない」と疑問に思っている方も多いかもしれません。
クラスが何であるのかは、後に解説していきます。ここではまだ詳細を理解しようとはせず、まずは、クラスがプログラムを包んでいる「括り」のようなものである点に着目してください。
クラスを記述する基本構文は、次のとおりです。
class クラス名 { クラスの実装内容 }
public
」についてところで、今回のMainの場合、キーワード「class
」の前に「public
」が付いています。この「public
」という語は何でしょうか? これは、アクセス修飾子と呼ばれるもので、このクラスのアクセスレベルを設定するものです。詳細は後述しますが、「public
」というは、このクラスが、他のすべてのクラスからアクセス可能であることを表しています。
とはいえ、いまのところ私たちのプログラムにはMain
クラス1つしかありません。ですので、アクセス修飾子には特に実用的な意味はありません。
public
を記述せず、「無指定」というアクセスレベルを設定しても、何も問題はありません(“アクセス修飾子を指定しない”という指定の仕方もあるのです!)。アクセス修飾子については、後述の解説を参照してください。
この基本構文に照らして、今回のHello worldプログラムのクラスを見てみましょう。
まずわかることは、クラス名が「Main
」であることです。
というのも、キーワード「class
」の次に「Main
」が来ているからです。
簡単ですね。
そして、クラスの実装内容を示す「{ }
」が、行末から5行目まで(つまりファイルの終端まで)続いていることがわかります。
つまり、今回のHello worldプログラムは、全体をMain
という名前のクラスがすっぽりと包んでいるということです。
クラスについて、現時点で注意しておきたいことはこれだけです。
では、さっそく { }
の中、つまり2行目以降へと読み進めて、実装内容を見てみることにしましょう。
──いえ、その前に、もう1つ確認しておきたいことがありました。それは、クラス名と、このソースファイルのファイル名との対応関係です。
今回の場合、クラス名は「Main
」です。そして、このプログラムのソースファイル名は「Main.java
」でしたね?
このように、Javaでは基本的に、ソースファイルのファイル名を「クラス名+.java
」というふうに付けることになっています。
もし興味があれば、ソースファイルの名前をまったく別の名前に変えてコンパイルしてみてください。きっとコンパイルエラーになってしまいます。
第2行目[編集]
続いて2行目を見てみましょう。
public static void main(String[] args){
この行は、「main
」という名前のメソッドを宣言している部分です。
「メソッド」とは、クラスが行う処理のことです。
「Main」はごく単純なサンプルなので、メソッドはこのメソッド1つだけですが、クラスには複数のメソッドを記述することができます。
メソッドが何であるのかについても詳しくは後述することにします。しかし、もしC言語をご存じであれば、メソッドとはC言語の「関数」に近いものであると考えておいてもよいかもしれません。 つまり、メソッドというものは、何らかのひとまとまりの処理を記述したものです。 そしてやはり関数同様、戻り値を返すしくみをもっています。
メソッドを記述する構文のアウトラインは次のとおりです。
戻り値の型 メソッド名 (引数の型 引数名 ) { メソッドの実装内容 }
さて、基本構文に照らして、「Main」の2行目を見てみましょう。
今回の場合、(少しわかりにくいかもしれませんが)「戻り値の型」に当たるのは「void
」です(やはりクラス同様、その前に修飾子が付いています。このメソッドの場合「public
」と「static
」がそれです)。
「戻り値の型」の後に来るのがメソッド名ですから、今回の場合 「main
」がメソッド名だということがわかります。
最初の語「public
」は、アクセス修飾子です。アクセス修飾子については、後述します。
次の語「static
」は、このメソッドが、staticメソッドというものであることを表しています。staticメソッドとは、そのメソッドが(インスタンスではなく)クラスに属するメソッドであることを表します。これも詳しくは後述します。
public
とstatic
の2語は、語順を逆に並べることもできます。そして実装部分は、行末の「{
」から4行目の「}
」までであることもわかります。
ここで注意すべき点は、メソッドが、クラスの中に記述されている点です。
メソッドというものは、必ずクラスの中に記述されます。クラスの外に直接メソッドを書くことはできません。
括弧の中に書かれた「String[] args
」は、引数です。mainメソッドが、String型の配列(String[]
)を引数に持つことを表しています。args
は引数に与えられた変数名です。
変数や配列、引数などについては、後述します。
なお、この部分は「String args[]
」と書くこともできます。また、args
という仮引数は、任意の名前に変えることができます。さて、実は今回のmainというメソッドには、特記すべきことがあります。
実は、このメソッドのような、
- アクセスレベルが
public
で - 引数は
String[]
を1つだけ取る - 名前が
main
の - staticなメソッド
は、特殊な意味を持ち得るのです。すなわち、
$ java Main
のように、java
コマンドで呼び出されたクラスは、自動的に上記のような条件を満たしたmainメソッドを実行することになっているのです。つまり、こうしたmainメソッドは、C言語のmain関数のような役割を果たします。
ただし、プログラム内にただ1つしか存在し得ないC言語のmain関数とは異なり、mainメソッドを持つクラスがプログラム内に複数あっても構いません。たとえばMain.java
に次のようなプログラムを書いたとしても問題はありません。
- 例
public class Main { public static void main(String[] args) { System.out.println("Hello, world."); } } class Arigatou { public static void main(String[] args) { Main.main(null); System.out.println("Thank you, world."); } }
これをコンパイルして、実行してみましょう。
$ javac Main.java $ java Main Hello, world. $ java Arigatou Hello, world. Thank you, world.
mainメソッドが2つあっても、プログラムの実行に問題がない点を確認してください。
なお、ここではArigatou
クラスからMain
クラスのmainメソッドも呼び出していますが、もちろん必要がなければ呼び出さなくても構いません。あくまで重要なのは、mainメソッドを持つクラスがプログラム内に複数あっても構わないという点です。
また、mainメソッドの引数であるString[]
には、java
コマンドで呼び出された際の引数(コマンドライン引数)が格納されます。少し脱線になりますが、ここでコマンドライン引数を利用した簡単なプログラム例(Echo.java
)を見てみましょう。
class Echo {
public static void main(String[] args) {
for (String arg: args) {
System.out.print(arg + " ");
}
System.out.println();
}
}
javac
でコンパイルし、実行すると、UNIXのecho
コマンドのような動作をします。
$ javac Echo.java $ java Echo Hello, world Hello, world「
java Echo Hello, world
」の「Hello,
」と「world
」が、String
の配列の要素として、args
に格納されている点に着目してください。第3行目[編集]
3行目を見てみましょう。
System.out.println("Hello, world.");
この行が「Hello, world.」という文字を画面に表示しているところです。つまり、この行に至って、ようやくプログラムの処理にたどり着いたわけです。
Hello worldプログラムは、この処理に至るまで2重に包まれています。 一番外側の包みはクラスです。そして次にメソッドという包みがあります。 これはオブジェクト指向言語の形式を如実に表しています。
もし、BASICでHello worldを書いたならば、
PRINT "Hello, world."
という1行だけで十分だったでしょう。しかし、Javaでプログラミングする場合、BASICのように直接処理を書くことはできません。必ずクラスやメソッドという包みを作り、その上でその中に処理を書きます。これが、Javaプログラミングの最も基本的な作法です。
printfとprintln[編集]
- ※ Hello World とは別の話題だが、しばらく間借り。
下記コードのように、printf
を使うと、ひとつの引用符の中に、変数を埋め込むことができます。
class test {
public static void main(String[] args) {
int old = 15;
System.out.printf("山田くんは%d歳\n", old);
}
}
- 出力結果
山田くんは15歳
「%d」は、10進数で表示する、という意味です。
改行を出力の末尾に追加する println
メソッドでは、このような変数の埋め込みはできません。
fとlnの末尾に付いた printfln または printlnf というメソッドは、Javaにはありません。
print
だけだと、改行を末尾に追加しません。
上記コードと同じ出力結果のコードは、下記のように「+」演算子で、文字列連結することでも書けます。
class test {
public static void main(String[] args) {
int old = 15;
System.out.println("山田くんは"+ old + "歳");
}
}
+ 演算子のとなりに文字列型のデータが来た場合、+演算子は連結の意味で解釈されます。
なので、下記のように整数型(int)など数値どうしを「+」演算した場合には、足し算になります。
class test {
public static void main(String[] args) {
int old = 15;
int ninengo = 2; // 2年の時間経過
System.out.println(old + ninengo);
}
}
- 出力結果
17
- 関連分野
JavaScriptでいう「テンプレート・リテラル」に相当する機能は、Javaには無い。
- ※ JavaScript に詳しくない人は、分からなかったら、上記の説明は読み飛ばしても構いません。