Java/Hello world

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

「Hello world」について[編集]

Wikipedia
ウィキペディア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.");
    }
}
参考
ソースファイルを保存する場所は、原則的にどこでも構いません。しかし、コマンド プロンプト(ターミナル)からアクセスしやすい場所に保存しておくと、後の作業が楽になります。そのため、Unix系であれば ~/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.javaC:\srcディレクトリに保存しているなら、まず
> cd C:\src
を実行してから(先頭の「>」はプロンプトを意味しています。入力はしません)、上記のjavacコマンドを実行します。Main.classが作成されたかどうかは、
> dir
を実行して確認することができます。
なお、こうしたコマンド プロンプトのコマンドの使い方については、MS-DOS/PC DOS入門で知ることができます。


参考
もし、クラスファイルが生成されず、何らかのエラーメッセージが表示された場合(すなわち、コンパイルエラーになった場合)は、入力したプログラムに間違いがないかどうかを確認します。コンパイルエラーに対するデバッグは、基本的に表示されたエラーメッセージを手がかりに行いますが、慣れないうちは、メッセージの内容が必ずしも理解しやすいとは限りません。デバッグする際の主な確認ポイントには、たとえば次のようなものがありますので、参考にしてください。
  • 全角文字を使っていないか?上記のプログラムは、すべて半角文字で入力してください。
    • 特に全角スペース「 」は目で見て確認できないので、「 」で検索するなどの方法での確認が必要です。
  • ファイル名が「Main.java」になっているか?
    • 「拡張子を隠す」設定にっていると、画面上では「Main.java」でも「Main.java.txt」などになっていることがあります。
  • 大文字と小文字を正確に使い分けているか?
  • プログラミング特有の記号類について
    • セミコロン(;)とコロン(:)を間違えていないか?
    • 行末のセミコロン(;)を忘れていないか?
    • 行末に余計なセミコロン(;)を付けていないか?
    • 引用符()、中括弧({ })、大括弧([ ])の対応はあっているか?

プログラムを実行する[編集]

最後にプログラムを実行します。次のようにコマンドを実行します。

 java Main

「Hello, world.」と表示されれば成功です。うまくいきましたか?

参考:コンパイルはうまくいくが、実行ができないという場合
コンパイルは通るのに、実行しようとするとjava.lang.NoClassDefFoundErrorが発生してしまうことがあります。
この原因はクラスパスの指定にあるかもしれません。
Windowsを使っている場合にこの現象が起こる可能性が高いので、ここではWindowsを前提に解説します。
(LinuxUNIXでよく使われる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メソッドとは、そのメソッドが(インスタンスではなく)クラスに属するメソッドであることを表します。これも詳しくは後述します。
なお、publicstaticの2語は、語順を逆に並べることもできます。

そして実装部分は、行末の「{」から4行目の「}」までであることもわかります。 ここで注意すべき点は、メソッドが、クラスの中に記述されている点です。 メソッドというものは、必ずクラスの中に記述されます。クラスの外に直接メソッドを書くことはできません。

参考
括弧の中に書かれた「String[] args」は、引数です。mainメソッドが、String型の配列String[])を引数に持つことを表しています。argsは引数に与えられた変数名です。
変数や配列、引数などについては、後述します。
なお、この部分は「String args[]」と書くこともできます。また、argsという仮引数は、任意の名前に変えることができます。

さて、実は今回のmainというメソッドには、特記すべきことがあります。

実は、このメソッドのような、

  • アクセスレベルがpublic
  • 引数はString[]を1つだけ取る
  • 名前がmain
  • staticなメソッド

は、特殊な意味を持ち得るのです。すなわち、

 $ java Main

のように、javaコマンドで呼び出されたクラスは、自動的に上記のような条件を満たしたmainメソッドを実行することになっているのです。つまり、こうしたmainメソッドは、C言語のmain関数のような役割を果たし、エントリーポイントと呼びます。

第3行目[編集]

3行目を見てみましょう。

         System.out.println("Hello, world.");

この行が「Hello, world.」という文字を画面に表示しているところです。つまり、この行に至って、ようやくプログラムの処理にたどり着いたわけです。

Hello worldプログラムは、この処理に至るまで2重に包まれています。 一番外側の包みはクラスです。そして次にメソッドという包みがあります。 これはオブジェクト指向言語の形式を如実に表しています。

もし、BASICでHello worldを書いたならば、

PRINT "Hello, world."

という1行だけで十分だったでしょう。しかし、Javaでプログラミングする場合、BASICのように直接処理を書くことはできません。必ずクラスやメソッドという包みを作り、その上でその中に処理を書きます。これが、Javaプログラミングの最も基本的な作法です。

このページ「Java/Hello world」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。