System.out.println() 解題

Revised: Jan./8th/2001

単純なスタンドアロンアプリケーションでは、標準出力への出力は次のように書く:

//行末で改行なし
	System.out.print();
//行末で改行付き
	System.out.println();

これは任意のクラスで自由に使える。何故だろうか? System.outSystem クラスのメンバ変数呼び出しであり、 print() メソッドは PrintStream クラスである。そんなことが許される理由は何だろうか?

System

System クラスは java.lang パッケージに含まれる。全てのクラスでは java.lang パッケージは自動的にインポートされている。したがって、 public 宣言が付いた System クラスは自由に使える。

但し、 System クラスはインスタンス化できない。System.java のソースコードを確認すると、コンストラクタprivate 宣言されていた。

System クラスはどこからでも参照できるが、インスタンス化は出来ないようになっている。

out

outSystem クラスで定義されたメンバ変数(フィールド)であり、既に開いている標準出力ストリームを意味する。修飾子public final static PrintStream であり、 static 宣言されているので、 System クラスをインスタンス化しなくとも、クラス名で直接アクセスできる。

また、この変数の型は PrintStream クラス型である。このクラスは java.io パッケージに含まれるが、 System クラスでは冒頭でこのクラスをインポートしているので、この使用法に関して問題はない。

この変数は、既に開いている標準出力ストリームをオブジェクトとして参照する。この使用法が変更されないように、 final 宣言がされており、事実上のパラメータとなっている。

print(), println()

これらのメソッドは PrintStream クラスで定義されているので、 PrintStream 型で定義されている変数 out をオブジェクトとしたメソッドになれる。

オブジェクトはいずこに

オブジェクトを明示する為に、参照型変数の代入をしてみよう。ここでは、 PrintStream 型の変数 out を、別の PrintStream 型の変数に代入している。System クラスのメンバ変数として定義されている out は、任意のクラスから System.out で参照できる:

PrintStream obj = System.out;
obj.println();

PrintStream 型変数である obj に対して、参照のコピーが行われている。参照先は Syste.out 、すなわち標準出力ストリームである。この標準出力ストリーム・オブジェクトのメソッド println() を呼び出しているわけである。

ここでは、オブジェクトを明示する為に新たに変数を定義して代入したが、直接メソッド呼び出しすれば、次のようになるわけだ:

System.out.println();

ネイティブメソッド

実際には、 System.in, System.out を標準入出力デバイスに関連付けるために、システムのネイティブな函数を利用している。順番としては、空の入出力ストリーム System.in, System.out を定義し、これをネイティブメソッドの中で PrintStream 型の標準入出力ストリームと関連付けている。標準入出力を要求すると、 Java VM はネイティブな函数 (DLL: Dynamic Link Library) を通して、OSのカーネルへ対応するデバイスの制御を受け渡しているわけだ。



Copyright © 2001 SUGAI, Manabu. All Rights Reserved.