概要
春なので、初心にかえって 「Hello world」を書いてみました。
皆さんご存じのとおり、「Hello world」は入門用のシンプルなコードです。
しかしその反面、その言語に入門したばかりの初心者には分かりづらい、特徴的な箇所も若干あります。
この投稿では、「Hello world」の特徴的な箇所を解説してみます。
たかが「Hello world」、されど「Hello world」。
HelloWorld.java
まずは、この投稿の主役となるコードを見てください。
ごくごく普通の「Hello world」です。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello, world");
}
}
hello, world
「Hello world」の特徴的な箇所
それでは、(一般的なJavaプログラムと比べて)「Hello world」の特徴的な記述を見てみましょう。
各項目には私の独断で「特殊度」をつけました。★が多いほど特殊(一般的なプログラムでは見かけない記述)ということになります。
package
宣言がない (特殊度: ★★★)
一般的なJavaプログラムはpackage
(パッケージ)宣言から始まります。
しかし、HelloWorld.java
には、package
宣言がありません。
package com.example.xyz;
package
宣言がないと、クラスは「デフォルトパッケージ」という特殊なパッケージに属することになります。
「デフォルトパッケージ」は「無名パッケージ」と呼ばれることもあります。
「デフォルトパッケージ」に属するクラスは、他のクラスからimport
(インポート)することができません。
import
宣言では、「パッケージ名を含めたクラス名1」を指定する必要があるからです。
import com.example.xyz.HelloWorld;
特殊度は?
他のクラスからimport
できないクラスは不便なので、「デフォルトパッケージ」はサンプルコードのような使い捨てのコードでしか使いません。
使い捨てでない一般的なプログラムでpackage
宣言が存在しないことはまずないので、特殊度は**★★★(3)**とします。
クラス宣言に、extends
がない (特殊度: ☆☆☆)
Javaでは、すべてのクラスはObject
クラスのサブクラスとなります。
Object
クラスの直接のサブクラスの場合、extends Object
の記述は省略することができます。
つまり、HelloWorld
クラスは、Object
クラスの直接のサブクラスとなります。
// 以下のクラス宣言と全く同じ意味
public class HelloWorld {
// ...
}
// Objectクラスの直接のサブクラスであることを明示
public class HelloWorld extends Object {
// ...
}
特殊度は?
extends Object
をわざわざ明記することは通常ありません2。
というわけで、特殊度は**☆☆☆(0)**です。
main
メソッドが定義されている (特殊度: ★☆☆)
main
メソッドは、特殊なメソッドです。
java
コマンドでは、実行時に指定されたクラスのmain
メソッドが呼び出される仕様となっています。
以下、java
コマンドの公式ドキュメントから引用します。
java コマンドは Java アプリケーションを起動します。これは、Java Runtime Environment を起動し、指定されたクラスをロードし、そのクラスの main メソッドを呼び出すことによって行われます。
このメソッドは、public および static として宣言する必要があります。また、値を返してはいけません。さらに、String 配列をパラメータとして指定できなければなりません。メソッド宣言の形式は次のとおりです。
public static void main(String[] args)
上記のとおり、以下がjava
コマンドから呼び出されるメソッドの条件となります。
- メソッド名が、
main
である - アクセス修飾子が、
public
である -
static
(静的メソッド)である - 戻り値が、
void
である - 引数が、
String[]
(String配列)である
なお、指定されたクラスに呼び出し可能なmain
メソッドが存在しない場合、java
コマンドは以下のようなエラーになります。
> java HelloWorld
エラー: メイン・メソッドがクラスHelloWorldで見つかりません。次のようにメイン・メソッドを定義してください。
public static void main(String[] args)
親切ですね。
特殊度は?
特に特殊な記述というわけではありませんが、規模の大きなプログラムの場合、殆どのクラスはmain
メソッドを持ちません。
もしかしたらmain
メソッドを使ったことがないJavaプログラマーもいるかもしれない3ので、特殊度は**★☆☆(1)**としておきます。
「Hello world」の具体的な処理
長くなったので、別投稿にしました。
→ System.out.println("hello, world")を読み解く
HelloWorld.java(冗長な記述)
ここまでの解説をコードに反映してみました。
コメントも沢山いれたので、読んでみてください。
// pacakege宣言を省略することで、このクラスはデフォルトパッケージに所属する
import java.lang.*;
// ※以下、java.langパッケージのクラスはパッケージ名の修飾なしで使用可能だが、例示のためにFQCNで記述する
// このクラスはObjectクラスの直接のサブクラスとなる
public class HelloWorld extends java.lang.Object {
// javaコマンドから呼び出される条件を備えたメソッドを定義する
public // ・アクセス修飾子が、publicである
static // ・static(静的メソッド)である
void // ・戻り値が、voidである
main // ・メソッド名が、mainである
(java.lang.String[] args) // ・引数が、String[](String配列)である
{
// Systemクラスのoutフィールドから、『「標準」出力ストリーム』を取得する
java.io.PrintStream ps = java.lang.System.out;
// Stringインスタンスを、文字列リテラルを使用せずに生成する
char data[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
java.lang.String str = new java.lang.String(data);
// printlnメソッドで、strをストリームに出力する
ps.println(str);
}
}
さいごに
さいごにもう一度、普通の「Hello world」を見てみましょう。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello, world");
}
}
こうしてみると、「Hello world」から色々と学べることがあるということが分かりました。
たかが「Hello world」、されど「Hello world」。
参考
- Java Language Specification - 7.4.2. Unnamed Packages
- Java Language Specification - 7.3. Compilation Units
リンク先がJava7なのは、なんとなく多くの人が使ってそうな気がしたからです。
この投稿の内容自体は、基本的にはどのバージョンでも同様に通用します。