JAVAプログラミングを始めよう

Javaの基礎 Javaプログラムは,ソースコードオブジェクトコードの2つの形態があります.ソースコードはプログラムのテキスト版で,テキストエディタを用いて作成したものです.オブジェクトコードはプログラムの実行形態です.オブジェクトコードはコンピュータ上で実行することができます.C/C++などのオブジェクトコードは,特定のCPU専用で,異なるプラットフォームでは実行できません.しかし,Javaはプラットフォーム非依存です.

Javaはプラットフォーム非依存を実現するために,コンパイル時にバイトコードと呼ばれる特定のCPUに依存しない命令を含んだオブジェクトファイルを生成します.このバイトコードはJava Virtual Machine(JVM)によって解釈できるように設定されています.

Javaのプラットフォーム非依存の鍵は,同じバイトコードをあらゆるプラットフォーム上のJVMで実行できる点にあります.

この章では,JAVA言語を用いた標準出力とよばれる画面(コンソール)への文字や数字の出力方法について学びます.このようなアプリケーションをコンソールアプリケーションといいます.Javaではこの他に,GUI(グラフィック・ユーザ・インターフェイス)を用いたアプリケーションアプレット(applet)があります.アプリケーションは,JVMによって直接実行することができます.しかし,アプレットを実行するにはwebブラウザが必要です.

出力メソッド(Output Method)

JavaにはSystem.out.println()という画面に表示するための出力メソッド(output method)} が用意されています.
このメソッドは引数として渡された文字列を出力し,その後改行文字を出力します.他にもSystem.out.print()メソッドもありますが,こちらは改行文字を出力しません.セミコロンはステートメントの終わりを示します.
System.out.println("Hello");
によって,2重引用符" "内の文字はそのまま標準出力に渡され表示されます.出力する文字列を途中で改行(new line)するには$\yen$nと2重引用符内で書きます.また,段落(tab)を取るには, 2重引用符内で$\yen$tと書きます.

例題 1..1   画面への出力
\framebox{
\begin{minipage}{13.65cm}
{\rm Hello world\\
初めてのJava\\
と画面に表示しなさい.ただし,初めてのJavaの前には段落をとるとします.}
\end{minipage}}

解答 Javaのプログラムでは必ずクラス名を決めなければなりません.ここではクラス名をHelloとします.Javaではapplet以外のプログラムでは,main()メソッドとよばれるものも必要となります.メソッドとは,あるまとまった処理を行なう一連のプログラムで,{から}までが1つのメソッドとなります.また, Javaで画面へ出力するには,System.out.println()メソッドを用います. そこで,次のようなプログラムを書きます.

class Hello
{
  public static void main(String[] args)
  {
    System.out.println("Hello world \n \t初めてのJava\n");
  }
}
実行結果

\begin{figure}\centering\includegraphics[width=7.8cm]{JAVAFIG/Hello.eps}
\end{figure}

このプログラムをエディタ(vi,emacs,秀丸,MKEditor,メモ帳等の文書を書く機能を持ったもの)を使って書き,Hello.Javaという名前を付けて保存します.Javaではファイル名はクラス名と同じでなければなりません.

次に,javaのコンパイラを用いてコンパイルします.JDKをインストールした場合,JDKをインストールしたディレクトリに移動し,次のコマンドをコマンドプロンプトで入力します.

javac Hello.java
エラーが発生しなかったら,次に
java Hello
とコマンドプロンプトで入力します.

コンパイラの仕事の一つはプログラムのテキストが正確かを解析することです.コンパイラはプログラムの意味は理解できないが,プログラムの構文については間違いを見つけることができます.よくある二つのプログラムエラーは次のようなものです.

  1. 構文エラー
  2. 型エラー
構文エラーとは,例えば次のようなものです.

public static void main(String[] args ; //)がない
{
    System.out.println("Hello Java"): // 違法文字 ':'

型エラーとは,用いる変数の型に応じて型を宣言しなければならないのに,間違った型を宣言してしまったりすることをいいます.

エラーメッセージは一般に式番号とコンパイラがたどりついた簡単なエラーの発生理由を含んでいます.エラーは発生順に訂正する習慣を身に着けるべきです.エラーの修正が済んだらまたコンパイルします.このステップはエディットーコンパイルーデバッグとよばれます.

コンパイラの仕事のもう一つの役割は,コード生成とよばれるコンピュータに分かる命令テキストにプログラムを変換することです.Javaコンパイラは,実行可能コードを生成するのではなく,バイトコード(byte code)を含んだオブジェクトファイルを作成します.バイトコードとは,特定のCPUに依存しない命令のことです.バイトコードはJava Virtual Machine(JVM)によって解釈できるように設計されています.このことにより,Javaはプラットフォーム非依存を実現させています.

コンパイルがうまくいくとバイトコードが作られるので,Javaインタープリタを呼び出してプログラムを実行することができます.プログラムを実行するには

java Hello
と入力します.

プログラムHello.javaの解説(Explanation of Hello.java)

クラスとオブジェクト

クラスとオブジェクトは,すべてのJavaプログラムの構築ブロックを形成しています.したがって,これらについて基本的なことを理解しておく必要があります.

オブジェクトとは,状態と動作の両方を定義する記憶領域のことです.記憶領域はメモリであることもディスクであることもあります.状態は一連の変数とその中の値によって表現されます.動作は一連のメソッドとそれによって実装されるロジックによって表現されます.したがって,オブジェクトとは,データとそれを操作するコードの組合せであると言えます.

クラスとは,オブジェクトを作成するための雛形(テンプレート)のことです.

練習問題 1..1   コンソールへの出力
こんにちは
誰々さん
と表示するプログラムを作成しなさい.ただし,誰々さんには自分の名前を入れます.

エスケープ文字 エスケープ文字には,次のようなものがあります.

エスケープ文字  機能
\b カーソルを1文字分戻す
\f 次のページの先頭にカーソルを移動する(改頁)
\n 次の行の先頭にカーソルを移動する(改行)
\r 同じ行の先頭にカーソルを移動する(復帰改行)
\t 次の水平タブ位置にカーソルを移動する(水平タブ)
\v 次の垂直タブ位置にカーソルを移動する(垂直タブ)
\\ \記号を示す
\' 引用符を示す
\" 2重引用符を示す
\0 ナル文字を示す
\DDD 8進数DDDで表される文字を示す
\uxxxx Unicode文字(xxxxは4桁の16進数定数)

例題 1..2   出力メソッドへの数値の挿入
\framebox{
\begin{minipage}{13.65cm}
次の文章を出力しなさい.\\
20世紀は2000年12月31日で終わった.
\end{minipage}} /I>

解答

class EndOfCentury
{
  public static void main(String[] args){
    System.out.println(20 + 世紀は" + "年" + 12 + "月" + 31 + "日で終わった.");
  }
}

実行結果

\begin{figure}\centering\includegraphics[width=7.8cm]{JAVAFIG/EndOfCentury.eps}
\end{figure}

当然,System.out.println("20世紀は200年12月31日で終わった.");と書くこともできます.ここでは,Javaの文字列の扱いがいかに柔軟であるかを示すために,このような書き方をしてみました.数字と文字を+演算子で結ぶと,数字を文字列に直し連結してくれます.

練習問題 1..2   出力メソッドへの数値の挿入
自分の生年月日を出力しなさい.

文字とリテラル(Characters and Literals)

文字とは文章を書く文字に10個の数字と句読点を含めたものをいいます.文字は整数としてコンピュータに格納されます.格納方法で最も有名なのがASCIIコード(ASCII code)です.ASCIIはAmerican Standart Code for Information Interchangeの略で,英数字をISOコードにパリティビットをつけた8ビットで表します.JavaではUnicodeを用いています.UnicodeはASCIIコードをそっくり取り込んでいるので,半角文字に関しては,ASCII文字感覚で用いることができます.

例えば大文字のAはASCIIコードでは,10進数で65として格納されます.ちなみに,65は2進数で表すと

$\displaystyle (65)_{10} = 2^{6} + 1 = (1000001)_{2}$

16進数で表すと

$\displaystyle (1000001)_{2} = 0100 \vert 0001 = (41)_{16} = {\rm0x41}$

8進数では

$\displaystyle (1000001)_{2} = 001 \vert 000 \vert 001 = (101)_{8} = 0101$

となります.

Unicodeでは,大文字のAは10進数で0065として格納されます.また,漢字を用いるときもそれがUnicodeで表現されていることを意識する必要はありません.

データ型の具体的な値,つまり定数のことをリテラル(literal)といいます.例えば,文字型(char)のリテラルの例として'A',String型のリテラルの例として上の例題の"20世紀",整数型のリテラルとして2000などがあります.

改行文字 '\n' は余白文字(whitespace character)の1つで,表示されない文字の1つです. \n で1つの文字を表しています.これと同じ方法で作られている文字には, '\t' (タブ)などがあります.

変数とその宣言(Variables and Their Declarations)

変数はコンピュータのメモリへの格納場所を表す識別子です.その場所に格納された情報を変数の値といいます.変数は使用する前に必ず宣言されなければなりません.変数の値を取り出すには,代入が用いられその構文は
変数 = 式;
となります.最初に式が求められ,その結果が変数に代入されます.ここで,等号"="はプログラミング言語では代入演算子です.

例えば,メモリに格納された整数型の変数mの値5を表示するには,

int m = 5;
System.out.println(m);
と書くことができます.

例題 1..3   数値の代入
\framebox{
\begin{minipage}{13.65cm}
{\rm 整数{\rm 44}を変数{\rm m}に代入し,式{\rm m + 33}の結果を{\rm n}に代入するプログラムを作成しなさい.}
\end{minipage}}

解答 整数44を変数mに代入するには,まず,整数44を格納するための場所と名前が必要なので,int m;と宣言します.同様に,nにはmと整数33の合計が格納されるので,int n;の宣言も必要です.出力は2重引用句の中は記された通りに出力されることを利用し,System.out.println("m= " + m);とすれば,何を出力しているのか分かりやすくなります.これより,次のようなプログラムとなります.

class Assignment
{
  public static void main(String[] args)
  {
    int m,n;
    m = 44;
    System.out.println("m =" + m);
    n = m + 33;
    System.out.println(" and n = " + n);
 }
}

実行結果

\begin{figure}\centering\includegraphics[width=7.8cm]{JAVAFIG/Assignment.eps}
\end{figure}

練習問題 1..3   数値の代入
整数44を変数mに代入し,式m/12の結果を予想し,自分の予想が正しいかプログラムを書いて調べなさい.

変数mとnは次のように考えることができます.

\begin{figure}\centering\includegraphics[width=4.9cm]{CPPPIC/fig1-1.eps}
\vskip -0.3cm
\end{figure}

これはまるで郵便受けのようです.変数名mが住所で,44は郵便受けの中身,そして型intが郵便の種類(速達,書留など)です.

この例題で,変数m,nはint m,n;と宣言されていますが,同じ型の変数はこのようにまとめて宣言することができます.

Javaプログラムでは,全ての変数は使う前に宣言されていなければなりません.

    [型修飾子] データ型 変数名

となります.

オブジェクト指向言語では,メソッド内で用いられる変数をローカル変数(local variable)といい,クラスのメンバ変数をフィールド(field)といいます.

変数の名前

変数名はその変数が何を表しているのかが分かりやすい名前を付けます.そして,その名前の付け方には,次のような規則があります.

これとは,別にJavaスタイルというものがあり,

height_of_boxよりもheightOfBoxと表すキャメルケースを用いる.

変数の初期化(Initializing Variables)

変数の初期化とは,初めて変数の宣言をしたときに変数に値を代入することです.多くの場合,変数を宣言するときに同時に初期化を行っておくほうが賢明です.変数の初期化は,
int x = 1024;
のように書きます.

例題 1..4   初期化していない変数
\framebox{
\begin{minipage}{13.65cm}
変数を初期化せずに用いた場合,次のプログラムは何を表示するか調べなさい.
\end{minipage}}

class Variable
{
  public static void main(String[] args)
  {
    int m;
    System.out.println("m = " + m);
  }
}

実行結果

\begin{figure}\centering\includegraphics[width=12.5cm]{JAVAFIG/Variable.eps}
\end{figure}

Javaでは,初期化されていない変数はコンパイルエラーとなります.このことにより,C言語やC++言語で問題であった隠れたエラーの原因が一つ解消されます.C言語と異なりJava言語では,変数は使う直前で定義します.そのことにより,プログラムが読みやすくなります.

プログラムトークン(Program Token)

コンピュータプログラムはトークン(token)と呼ばれる要素の並びです.トークンはintなどのキーワード,mainなどの識別子,{などの句読点,'+'などの演算子を含んでいます.このプログラムをコンパイルするとき,コンパイラはソースコードを走査し,構文解析します.もし,構文エラーを見つけると,コンパイルをやめエラーメッセージを出します.例えば,文の終わりにセミコロンを付けるのを忘れたりすると,セミコロンが欠けているとのメッセージを出します.しかし,括弧を閉じるのを忘れたり,ダブルコーテーションの2つ目を忘れたりした場合は,コンパイラはプログラムのどこかがおかしいとのエラーメッセージを出すだけで,何がおかしいのかは自分で見つけなくてはなりません.

例題 1..5   プログラムトークン
\framebox{
\begin{minipage}{13.65cm}
次のプログラムには何個のトークンがあるか調べなさい.
\end{minipage}}

public static void main(String[] args)
{ // "n = 44"を表示します.これはコメントです.
/* これもコメントで,複数行にまたがるときに用います.*/
/** これもコメントで,これはjavadocというソフトウェアをもちいてドキュメントを
生成するときに用います**/
    int n=44;
    System.out.println("n = " + n);
}

解答 このソースコードには28個のトークンがあります. "public", "static", "void", "(", "String", "[", "]", "args", ")", "{", "int", "n", "=", "44", ";", "System", ".","out",".", "println", "(", "n" , "=", "+", "n", ")",";", "}"

コンパイラはコメントは無視するので,トークンの数には含まれません.

定数(Constant)

final
をつけます.finalが付くとこの変数はこれが最後の形となり,その後値を変えることができなくなります.つまり,定数ということです.定数は,宣言されるときに初期化もされなければなりません.

例題 1..6   定数の指定
\framebox{
\begin{minipage}{13.65cm}
次のプログラムは定数の定義のしかたを表しています.
\end{minipage}}

class UsefulConstant;
{
    public final int MAXINT = 2147483647;
    public final float KM_PER_MI = 1.60934f;
    public final int SCREEN_WIDTH = 640;
}

定数は大文字であらわすのが決まりになっています.

整数と実数(Integers and Real Numbers)

Javaでは数値を実数と整数で区別します.もっと詳しくいうと,1/2と1/2.0ではまったく違う値になります.1/2は0になり,1/2.0は0.5になります.これは,/という記号が商を表すということで理解できます.

Javaの基本データ型の詳しい紹介は2章で行ないますが,プログラミングは"習うより慣れろ"なので,幾つか紹介しておきます.

例題 1..7   基本データ型(=の両側にはスペースをいれるようにする)
\framebox{
\begin{minipage}{13.65cm}
基本データ型を調べなさい.
\end{minipage}}

char c = 'A'; /* 文字型*/
boolean b = true; /* 論理型*/
byte b = 1; /* バイト型(-128 〜 127)*/
short k = 32456; /* 整数型(-32,768 〜 32,767)*/
int i = 2442343434; /* 整数型(-2{31} 〜 2{31}-1の10進整数)*/
long l = 1234L; /* 長い整数(最後尾にLまたはlを付ける)*/
float f = 124.56f; /* 実数型(小数点または10の累乗で表し,単精度)*/
double d = 3.1415E3; /*実数型(floatと同形式)d=3141.5を表す*/

charはcharacter(文字)の略,int はinteger(整数),floatはfloat(浮動小数点)のことです.Javaではlong型の値には末尾にLまたはlをつける必要があります.floatも末尾にfをつけます.

浮動小数点出力(Floating Point Output)

次のような小数点を含んだデータX,Y,Zがあります.

  X[i] Y[i] Z[i]
1 12.24 13.456 234.2345
2 23.345, 32.12, 26.1235
3 432.2, 67.3, 45.2331

これを

for(int i=1;i <= 3; i++){
    System.out.println(X[i] + " " + Y[i] + " " + Z[i]);
}
と書くと,
12.24 13.345 234.234
23.345 32.12 26.1235
432.2 67.3 45.2331
と表示されます.

表記(Representation)

Javaでは10進数(decimal),8進数(octagonal),16進数(hexadecimal),指数(exponent)の表記が可能です.8進数の表記には0を数字の前に付け,16進数では0xを付ける.例えば,10進数40を16進数に直すと

    40 = 2 × 16 + 8
となるので0x28となります.Javaでは,
System.out.println(0x28);
と書くと,40と表示されます.では,10進数を40を16進数で表すには,どうすればよいでしょうか.Javaのライブラリには,Integerラッパークラスとよばれるものがあり,
int m = 40
Integer.toString(m,16);
と書くことにより,16進数に変換できます.この他にも,

String m = "40"
Integer.parseInt(m,16);
と書くことにより,16進数で40になる数に変換できます.

実行結果

\begin{figure}\centering\includegraphics[width=7.8cm]{JAVAFIG/HexConversion.eps}
\end{figure}

練習問題 1..4   表記
10進数40を16進数と8進数で出力するプログラムを作成しなさい.

クラスとメソッドの基礎

クラスとオブジェクトはJavaのプログラムの構築ブロックであるといいました.そこで,ここでは,クラスとオブジェクトがどのように作成され用いられるのか見てみます. クラスを理解するために,例として図形を考えましょう.図形には色々ありますが,例えば三角形を思い浮かべると,三角形には底辺と高さがあり,これによって面積が求まります.この三角形の属性である底辺と高さ,また,面積を求める方法などを1つのまとまりとしたものを三角形クラスといいます.このとき,底辺や高さをフィールド(フィールド変数)といい,面積を求めるための動作をメソッドといいます.

この三角形クラスの宣言は,識別子classのあとにクラス名がきて,中括弧{から中括弧}までが本体となります.

クラス宣言(Class Declarations)

クラス宣言を用いて上の事柄を宣言すると次のようになります.

class Triangle
{
  private double base, height; //フィールド
  public void assign(double b, double h) //代入メソッド
  {
    base = b;
    height = h;
  public double area()
  {
    return base*height/2;
  }   public void display();
  {
    System.out.println("底辺" + base + "高さ" + height + "の三角形の面積は" + area());
  }
}

ここで,classはクラス宣言を示すキーワードで,次のTriangleはこのクラスの名前です.{と}に囲まれた中は,クラスのフィールドとメソッドと呼ばれ,メンバどうしの名前が重複しなければ,どのような名前でも使えます.また,クラスのメンバはディフォルトでは非公開 (private) メンバになります.したがって,クラスの外から参照する必要のあるコンストラクタやメソッドは公開(public)にする必要があります. 公開にするにはpublicを付けます.逆に,フィールドは原則非公開(private)にする必要があります.なぜならば,フィールドが公開になっていると,クラスの外部からフィールド値の変更が可能となり,コントロールができなくなってしまいます.このように,フィールドを非公開にして,外部からアクセルできなくすることをカプセル化(encapsulation)といいます.これは,オブジェクト指向プログラミングの3つの原則の1つです.

クラスのオブジェクトを作る

このクラスを実際に使うには,変数を宣言して,その実体を用意する必要があります.この実体をオブジェクトといいます.Triangle t = new Triangle()で,tはTriangleクラスのオブジェクトとして宣言されます.よって,t自身がフィールド変数,baseとheightを持っています.また,オブジェクトtはメソッド assign(), area(), display()をよぶことができます.ここで,注意して欲しいのは,

メンバ関数display()は,その持ち主の名前をつけて,t.display()というように用いられます.
実際,メソッドはこのように用いるしかありません.

オブジェクトtは普通の変数のように宣言されます.この型はTriangleです.これはユーザ定義型(抽象データ型)として考えることができます.

Javaでは,int , float, doubleなどの型にTriangle型を付け加えることができます.これはオブジェクト t を次のように考えることで理解できます.

\begin{figure}\centering
\includegraphics[width=4.35cm]{CPPPIC/fig10-1.eps}
\end{figure}

また,オブジェクトtを宣言することを,オブジェクトのインスタンス化(instanciation)といい,オブジェクトtをTriangleクラスのインスタンスといいます.インスタンスとは,そのクラスの特定事例だと考えれば分かりやすいでしょう.

クラスを用いたプログラム

例題 1..8   三角形クラス
\framebox{
\begin{minipage}{13.65cm}
{\rm 底辺18,高さ24.5の三角形の面積を求めるプログラムを{\rm Triangle}クラスを用いて作成しなさい.}
\end{minipage}}

解答

  1. Triangleクラスの宣言を行います.フィールドはbaseとheightとします.
  2. メソッドの定義を行います.メソッドの定義は
    戻り値のデータ型 メソッド名(仮引数の型 仮引数)

    {
    }
    で行います.したがって,
    public void assign(double b, double h)  {
    base = b;
    height = h;
    }
    と定義すると,Triangleクラスのフィールド変数baseにassignメソッドで引いてきた値bが代入され,heightにhの値が代入されます.これより,baseとheightをTriangleクラスの他のメソッドで用いることができます.
  3. 最後にmainメソッドを用いるためのクラスTriangleIniクラスを作成し,mainメソッド内でTriangleクラス型のオブジェクトを作り,三角形の面積を求めます.

class Triangle
{
  private double base, height;

  public void assign(double, double)
{
    base = b;
    height = h;
    public double area()
    {
      return base*height/2;
    }
    public void display()
    {
      System.out.println("底辺" + base + "高さ" + height + "の三角形の面積は" + area());
    }
  };
} class TriangleIni
{
  public static void main(String[] args)
  {
    Triangle t = new Triangle();
    t.assign(18,24.5);
    t.display();   }
}

実行結果

\begin{figure}\centering
\includegraphics[width=8.8cm]{JAVAFIG/TriangleIni.eps}
\end{figure}

この例題から分かるように,Javaのプログラムを学ぶには,メソッドについて学ばなければなりません.次の章からはメソッドで用いる順接,選択,反復について学んだあと,メソッドの用い方について学んでいきます.

確認問題 1..1  

1. Javaの3通りコメントの方法を示せ.

2. 次のCスタイルのコメントはどこがいけないのか説明しなさい.

cout << "Hello, /* 変更 */ World. \n";

3. 宣言は何をするものか説明しなさい.

4. Javaで最も短いプログラムは何か.

5. 次の宣言はどこがいけないか

int first = 22, last = 99, new = 44, old = 66;

6. 次の文の誤りを見つけ,正しなさい.

int double=44;

7. ASCIIコードが100である文字を見つけるためにはどんなプログラムを書けばよいか

8. 次のプログラム中の予約語,識別子,演算子,リテラル,句読点シンボル,コメントを捜し出しなさい.

class Exercise

{

public static void main(String[] args)

{

int n;

n *= 3; // n = n*3

System.out.println("n = " + n);

}

}

9. 次の2つの文の違いを説明しなさい.

char c = 'A';

char c = 65;

10. aのASCIIコードを見つけるコードを書きなさい.

演習問題 1..1  

1. 次のプログラムの誤りを見つけなさい.

class UndeclaredInt
  public static void main(String[] args)
{
    // "n=22"を表示:
    n = 22;
    System.out.println("n = " + n);
}

2. 次のような実行結果を得られるように,プログラムの中の□を埋めて,プログラムを完成しなさい.

Mainは最初に呼び出されるメソッド.
    System.out.printlnは表示するためのメソッド.

class FillBlank
{
  public static void main(String[] args)
{
    System.out.println("Mainは最初に呼び出されるメソッド.□ System.out.printlnは表示するためのメソッド.");
  }
}

3. 以下の項目で,実数型で表す必要のあるものはどれか.

ア 体重の平均を計算します.

イ 人数の合計をカウントします.

ウ 実行回数をカウントアップします.

4. 以下の空欄を埋めよ.

10進数 16進数 8進数
18
0x25
012
8

5. 以下にJavaの構文で表した数字があります.同じ値のものどうしのグループに分けよ.

.25e2, 0x25, 25, 012, 37, 8, e1, 8.e0