概要

春なので、初心にかえって 「Hello world」を書いてみました。
皆さんご存じのとおり、「Hello world」は入門用のシンプルなコードです。
しかしその反面、その言語に入門したばかりの初心者には分かりづらい、特徴的な箇所も若干あります。

この投稿では、「Hello world」の特徴的な箇所を解説してみます。
たかが「Hello world」、されど「Hello world」。

HelloWorld.java

まずは、この投稿の主役となるコードを見てください。
ごくごく普通の「Hello world」です。

HelloWorld.java
public class HelloWorld {

  public static void main(String[] args) {
    System.out.println("hello, world");
  }

}
HelloWorld.classの実行結果
hello, world

「Hello world」の特徴的な箇所

それでは、(一般的なJavaプログラムと比べて)「Hello world」の特徴的な記述を見てみましょう。
各項目には私の独断で「特殊度」をつけました。★が多いほど特殊(一般的なプログラムでは見かけない記述)ということになります。

package宣言がない (特殊度: ★★★)

一般的なJavaプログラムはpackage(パッケージ)宣言から始まります。
しかし、HelloWorld.javaには、package宣言がありません。

package宣言の例
package com.example.xyz;

package宣言がないと、クラスは「デフォルトパッケージ」という特殊なパッケージに属することになります。
「デフォルトパッケージ」は「無名パッケージ」と呼ばれることもあります。

「デフォルトパッケージ」に属するクラスは、他のクラスからimport(インポート)することができません。
import宣言では、「パッケージ名を含めたクラス名1」を指定する必要があるからです。

import宣言の例
import com.example.xyz.HelloWorld;

特殊度は?

他のクラスからimportできないクラスは不便なので、「デフォルトパッケージ」はサンプルコードのような使い捨てのコードでしか使いません。

使い捨てでない一般的なプログラムでpackage宣言が存在しないことはまずないので、特殊度は★★★(3)とします。

クラス宣言に、extendsがない (特殊度: ☆☆☆)

Javaでは、すべてのクラスはObjectクラスのサブクラスとなります。
Objectクラスの直接のサブクラスの場合、extends Objectの記述は省略することができます。
つまり、HelloWorldクラスは、Objectクラスの直接のサブクラスとなります。

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コマンドは以下のようなエラーになります。

mainメソッドが存在しない場合のエラー例
> java HelloWorld
エラー: メイン・メソッドがクラスHelloWorldで見つかりません。次のようにメイン・メソッドを定義してください。
   public static void main(String[] args)

親切ですね。

特殊度は?

特に特殊な記述というわけではありませんが、規模の大きなプログラムの場合、殆どのクラスはmainメソッドを持ちません。
もしかしたらmainメソッドを使ったことがないJavaプログラマーもいるかもしれない3ので、特殊度は★☆☆(1)としておきます。

「Hello world」の具体的な処理

長くなったので、別投稿にしました。
System.out.println("hello, world")を読み解く

HelloWorld.java(冗長な記述)

ここまでの解説をコードに反映してみました。
コメントも沢山いれたので、読んでみてください。

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」を見てみましょう。

HelloWorld.java
public class HelloWorld {

  public static void main(String[] args) {
    System.out.println("hello, world");
  }

}

こうしてみると、「Hello world」から色々と学べることがあるということが分かりました。
たかが「Hello world」、されど「Hello world」。

参考

リンク先がJava7なのは、なんとなく多くの人が使ってそうな気がしたからです。
この投稿の内容自体は、基本的にはどのバージョンでも同様に通用します。


  1. 完全修飾クラス名。「Fully Qualified Class Name」を略して「FQCN」といわれます。 

  2. 私自身、この記事のような「説明用のコード」でしかみたことがないです。 

  3. サーバサイドプログラムやフレームワークを使用している場合など、mainメソッドを記述しなくても動作するプログラムは多々あります。 

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.