Top Banner
プログラミング言語 Java 学習用テキスト 2008.12.1 PDF 初版 三谷 本テキストは、大学で初めて Java を学習する学生のために作成した講義資料を、総合的にわかりやすくま とめ直したものです。プログラミングの経験のない方も、本テキストだけで十分プログラミングを習得できる よう丁寧な解説を心がけました。また、Java 言語に特有のオブジェクト指向についても理解を深められるよ う、概念ごとに章を区切って学習できる構成になっています。 本テキストの内容は、出版社の編集を経て「独りで習う Java(三谷純著, 翔泳社、ISBN 4798109177 )」 として出版されています。書籍は 2 色刷りで、各項目が見開きで完結するよう、わかりやすく編纂されていま すので、継続した学習のために書籍の購入もご検討いただければ幸いです。 非営利目的であり、原著作者のクレジット表示「(C) 2008 三谷純」がある限り、本テキストは自由に使用 していただけます。
134

プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

Mar 23, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

プログラミング言語 Java

学習用テキスト

2008.12.1 PDF版 初版

三谷 純 著

本テキストは、大学で初めて Java を学習する学生のために作成した講義資料を、総合的にわかりやすくま

とめ直したものです。プログラミングの経験のない方も、本テキストだけで十分プログラミングを習得できる

よう丁寧な解説を心がけました。また、Java 言語に特有のオブジェクト指向についても理解を深められるよ

う、概念ごとに章を区切って学習できる構成になっています。

本テキストの内容は、出版社の編集を経て「独りで習うJava(三谷純著, 翔泳社、ISBN 4798109177)」

として出版されています。書籍は2色刷りで、各項目が見開きで完結するよう、わかりやすく編纂されていま

すので、継続した学習のために書籍の購入もご検討いただければ幸いです。

非営利目的であり、原著作者のクレジット表示「(C) 2008 三谷純」がある限り、本テキストは自由に使用

していただけます。

Page 2: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

2

目次

第 1 章 はじめに ................................................................................................................................................... 4

1-1 プログラムのしくみとJAVA言語 .................................................................................................................... 4 1-2 はじめてのJAVAプログラムの作成................................................................................................................. 5 1-3 コンパイルと実行 ............................................................................................................................................. 6 1-4 JAVA言語によるプログラミングとは .............................................................................................................. 8

第 2 章 JAVAの基本 .......................................................................................................................................... 10

2-1 画面へ文字を出力する.................................................................................................................................... 10 2-2 変数 .................................................................................................................................................................. 11 2-3 算術演算子と式 ............................................................................................................................................... 14 2-4 コメント .......................................................................................................................................................... 15 2-5 型変換 .............................................................................................................................................................. 16 2-6 配列 .................................................................................................................................................................. 18 2-7 コマンドライン引数 ....................................................................................................................................... 21

第 3 章 プログラムの流れを制御する ................................................................................................................ 24

3-1 処理の条件分岐 ............................................................................................................................................... 24 3-2 コードのブロックとインデント .................................................................................................................... 27 3-3 ループ処理の流れの変更 ................................................................................................................................ 33 3-4 ループのネスト ............................................................................................................................................... 34 3-5 処理の場合分け ............................................................................................................................................... 35 3-6 論理演算子 ...................................................................................................................................................... 37

第 4 章 クラスとメソッド .................................................................................................................................. 40

4-1 クラスとは ...................................................................................................................................................... 40 4-2 クラスの定義とオブジェクトの作成☆ ......................................................................................................... 41 4-3 参照 .................................................................................................................................................................. 43 4-4 メソッド .......................................................................................................................................................... 44 4-5 メソッドの引数と戻り値 ................................................................................................................................ 46

第 5 章 クラスのはたらき .................................................................................................................................. 50

5-1 コンストラクタ ............................................................................................................................................... 50 5-2 コンストラクタのオーバーロード ................................................................................................................. 53 5-3 THISキーワード .............................................................................................................................................. 54 5-4 メソッドのオーバーロード ............................................................................................................................ 56 5-5 静的変数 .......................................................................................................................................................... 56 5-6 静的メソッド ................................................................................................................................................... 58 5-7 MATHクラス ................................................................................................................................................... 59

第 6 章 継承 ........................................................................................................................................................ 62

6-1 継承とは .......................................................................................................................................................... 62 6-2 変数、メソッド、コンストラクタの継承 ..................................................................................................... 63

Page 3: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

3

6-3 メソッドのオーバーライド ............................................................................................................................ 67 6-4 クラスの継承と参照 ....................................................................................................................................... 70 6-5 修飾子 .............................................................................................................................................................. 72 6-6 抽象クラス ...................................................................................................................................................... 73

第 7 章 インターフェイスとパッケージ ............................................................................................................. 77

7-1 インターフェイスとは.................................................................................................................................... 77 7-2 インターフェイスの使い方 ............................................................................................................................ 78 7-3 INSTANCEOF演算子 ........................................................................................................................................ 80 7-4 API仕様書の見方 ........................................................................................................................................... 81 7-5 パッケージの利用 ........................................................................................................................................... 83 7-6 パッケージの作成 ........................................................................................................................................... 85

第 8 章 例外処理 ................................................................................................................................................. 88

8-1 例外の発生と受け取り.................................................................................................................................... 88 8-2 ユーザーが入力する値への対処 .................................................................................................................... 90 8-3 CATCHブロックの検索 ................................................................................................................................... 92 8-4 例外の作成と送出 ........................................................................................................................................... 93 8-5 メソッドの外への例外の送出 ........................................................................................................................ 94

第 9 章 入出力..................................................................................................................................................... 97

9-1 ファイルへの出力 ........................................................................................................................................... 97 9-2 ファイルからの入力 ....................................................................................................................................... 98 9-3 ファイルの内容のトークン化 ........................................................................................................................ 99

第 10 章 アプレットの基本 ................................................................................................................................ 102

10-1 初めてのアプレット .................................................................................................................................... 102 10-2 アプレットの実行 ........................................................................................................................................ 103 10-3 アプレットのグラフィック ......................................................................................................................... 104

第 11 章 アプレットの応用 ................................................................................................................................. 111

11-1 アプレットのマウス操作 .............................................................................................................................. 111 11-2 AWTの使用 .................................................................................................................................................. 115 11-3 アニメーション表示 ..................................................................................................................................... 119 11-4 ダブルバッファリング................................................................................................................................. 121

Page 4: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

4

第 1 章 はじめに

1-1 プログラムのしくみと Java言語

■ コンピュータに命令を実行させるには、プログラム用の言語で命令を記述し、それをコンピュータが理解

できる機械語に翻訳します。

1+1の足し算をコンピュータに計算させるにはどうすればよいでしょう。コンピュータに対して「1と1を

足し合わせて、その結果を表示しなさい」という命令を伝える必要があります。しかしコンピュータが理解で

きる言葉は数字の「0」と「1」の並びだけだということを、皆さんもどこかで聞いたことがあると思います。

このような0と1で表された言葉を機械語といいます。そのため、コンピュータに何か命令を伝えるには、私

たち人間が読み書きできる言葉をコンピュータが理解できる機械語に翻訳する必要があります。

<イラスト>

人間 → (人間の理解できる言語)

翻訳

コンピュータ ← (コンピュータの理解できる言葉)

私たちが読み書きできる言葉には、もちろん私たちが日常使っている「日本語」がありますが、日常使用し

ている言葉は厳密な命令を必要とするコンピュータの処理を記述するのには残念ながら適していません。そこ

で考え出されたのがプログラムを作るための専用言語です。プログラム用の言語には、C 言語や C++、Perl

など様々なものがありますが、本書ではJavaという言語を学習します。

Java言語で書かれた命令文(プログラムコード)は、コンパイラ、インタプリタという2つのソフトウェ

アによって機械語に翻訳されます。

<イラスト>

Java言語で書かれたプログラムコード→(コンパイラ)→中間コード→(インタプリタ)→機械語

そのため、私たちはJava言語をマスターすれば、コンピュータに意図した処理を行わせることができるよ

うになるのです。

■まとめ■

・本書ではプログラムを作るための専用言語であるJava言語を学習します。

・Java言語で書かれたプログラムコードは、コンパイラ、インタプリタという 2つのソフトウェアによっ

て機械語に翻訳されて実行されます。

【コラム:コンパイラとインタプリタの2つのソフトを介して翻訳されるわけ】

Javaの大きな特徴の1つとして、あるOS上でコンパイルした中間コードが様々なOS上で動作することが

挙げられます。つまりWindows上でコンパイルした中間コードがMacintoshやLinux上でも動作します(C

や C++言語では、OS毎にコードをコンパイルしなおす必要があります)。Javaでは、コンパイラによって中

Page 5: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

5

間コード(クラスファイル)が作成され、これをインタプリタが読み込んでコンピュータに処理を実行させま

す。このインタプリタが各 OS毎に独自のものが準備されているため、同じ中間コードを異なる OSで実行す

ることができるのです。

1-2 はじめての Javaプログラムの作成

■ パソコンでJava言語のプログラミングを行うための準備をし、簡単なJavaのプログラムを作成してみ

ます。

◆プログラミングの準備

Java 言語でプログラムを作成し、それをコンピュータで実行するには前節で説明したようなコンパイラ、

インタプリタなどを事前に準備しておく必要があります。

最も一般的な方法として、Sun Microsystems 社の JDK(Java2 SDK Standard Edition)をインス

トールして使用することをお勧めします。これ以外にもJava言語でプログラムを作成するためのツールはい

くつかあります。職場や学校などで、予め別のツールが用意されている場合は、それらのマニュアルを参考に

してください。

JDKを使ったプログラミングの準備を行う方法は付録にまとめてありますので、そちらをご覧ください。

メモ Javaのプログラミングの練習を行うためのフォルダを事前に作成しておきましょう。例

えば、C ドライブの下に、「java」という名前のフォルダを作って、これから作成するプログ

ラムコードは全てそこに保存するようにすると便利です。

◆Javaのコードの入力

次のコードをメモ帳などのテキストエディタに入力して、Example1.javaという名前で保存しましょう。

Example1.java

class Example1 {

public static void main(String args[]) {

System.out.println("はじめてのJavaプログラム");

}

}

メモ メモ帳は[スタート]→[プログラム]→[アクセサリ]→[メモ帳]を選択して起動できます。メモ帳で保存

する時には、ファイルの種類で「すべてのファイル」を選択する必要がありますので注意しましょう。

メモ プログラムをテキスト形式で記述したものをコード、ソースコード、またはプログラムコードなどと呼び

「Example.java」と入力します

「すべてのファイル」を選択します

Page 6: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

6

ます。コードの作成にはメモ帳などのテキストエディタを使用します。Word や一太郎のようなワープロソフ

トは使用しないようにしましょう。ワープロソフトで作成したファイルには、文字の大きさや用紙のサイズの

ような、プログラムには必要の無い情報が含まれてしまうためです。

ここで入力したExample1.javaは、コンピュータに対して『「はじめてのJavaプログラム」という文字

を表示しなさい』と命令するコードです。

本書で掲載されているコードを実際にテキストエディタで入力するときは次のことに注意しましょう。

・ 保存するときにはファイルの拡張子を.javaにする(ファイルの名前の後ろに.javaをつけます)。

・ 英数字は半角で入力する。

・ 英字の大文字と小文字の違いに注意する。

・ 単語と単語の間には空白(スペースまたはタブ Tab)を入れる。

・ 外見の似ている文字に注意する。

・【0】"数字のゼロ"と【o】"英字の小文字のオー"と【O】"英字の大文字のオー"

・【1】"数字のイチ"と【I】"英字の大文字のアイ"と【l】"英字の小文字のエル"

・【{}】"中括弧"と【()】"小括弧"と【[]】"カギ括弧"

・【;】"セミコロン"と【:】"コロン"

・【.】"ピリオド"と【,】"カンマ"

■まとめ■

・Java言語でプログラムを作成し、実行するにはSun Microsystems社のJDKを使用するのが一般的で

す。JDKをインストールするには本書の付録を参考にしましょう。

・コードは「メモ帳」などのエディタで入力します。

・コードをファイルに保存するときには拡張子を.javaにします。

1-3 コンパイルと実行

■ Java言語で記述したコードをコンパイルし、コンピュータで実行してみます。

前節で作成したExample1.javaはJava言語で書かれたコードです。このままではコンピュータは内容を

理解できないため、コンピュータが理解して実行できる形に翻訳する必要があります。この翻訳作業のことを

コンパイルと呼びます(コンパイルを行うソフトウェアのことをコンパイラと呼びます)。Javaでは、コード

をコンパイルすると拡張子が.classのクラスファイルが作成されます。このクラスファイルをインタプリタ

が読み込んでコンピュータが実際の処理を行います。

「付録」の方法でWindowsにJDKをインストールした場合、javacというコマンドでコードをコンパイル

し、javaというコマンドを用いてプログラムを実行できます。

前節で作成したコードをコンパイルして実行するには次の手順を行います。

1.コマンドプロンプト(MS-DOSプロンプト)を起動する

2.cd というコマンドを使用してコードが保存されているディレクトリに移動する

(「ディレクトリ」は「フォルダ」と同じものを指します)

3.javac というコマンドを使用してコードをコンパイルする

4.java というコマンドを使用してプログラムを実行する

メモ コマンドプロンプトは[スタート]→[プログラム]→[アクセサリ]→[コマンドプロンプト]を選択して

Page 7: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

7

起動します。

Cドライブの"java"という名前のディレクトリ(フォルダのことです)にExample1.javaを保存した場

合(c:¥java¥Example1.java というファイルを作成した場合)、コマンドプロンプトを起動して次のよう

にコンパイルと実行を行います。

1.[cd c:¥javaEnter]と入力する

(1-2 [dirEnter]と入力し、一覧の中にExample1.javaがあることを確認します)

2.[javac Example1.javaEnter]と入力する

(2-2 [dirEnter]と入力し、一覧の中にExample1.classがあることを確認します)

3.[java Example1Enter]と入力する

メモ cd,javac,javaなどのコマンドの後ろには半角スペースで空白を入れます。dirコマンドでディレ

クトリに存在するファイルの一覧を表示できます。

上記の方法を行うと、画面に「はじめてのJavaプログラム」という文字が表示されます。Example1.java

ファイルにJava言語で記述した命令がパソコンによって実行されました!

この様子は図1-1のようになります。

図1-1.Example1.javaをコンパイルして実行した様子

■まとめ■

・コンピュータはJava言語で記述されたコードを直接理解することができないため、コンパイルという翻

訳作業を行う必要があります。

・コードをコンパイルするには、コマンドプロンプトでjavacというコマンドを使用します。

・コンパイルして生成されるクラスファイルを実行するにはjavaというコマンドを使用します。

【コラム:階層の深いディレクトリへの移動】

ディレクトリを移動します

コンパイルします

実行します

Page 8: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

8

Cドライブの"java"という名前のディレクトリの中に、さらに"examples"という名前のディレク

トリを作成し、そこにExample1.javaを保存したとします。その場合は、

cd c:¥javaEnter

と入力してから、

cd examplesEnter

と入力して、ファイルを保存したディレクトリへ移動できます。また、

cd c:¥java¥examplesEnter

と入力すれば一回の操作で移動することができます。

1-4 Java言語によるプログラミングとは

■ Java言語はオブジェクト指向型言語です。オブジェクトを組み合わせてプログラムを作っていく様子は、

部品を組み合わせてロボットを組み立てる様子にたとえることができます。

Java はプログラミング言語の分類の中ではオブジェクト指向型言語といわれ、オブジェクトを組み合わせ

ることで1つのプログラムを作り上げていきます。オブジェクト指向の概念は本書を通して学習していきます

が、ロボット作りにたとえると、ここでの「オブジェクト」は「ロボットの部品」と見なすことができます。

つまりJava言語によるプログラミングは、部品を組み合わせてロボットを組み立てていく作業に似ていると

言うことができます。もちろん、プログラムの部品はロボットの部品のように目で見て手で触れるものではあ

りませんが、イメージとして部品のようなプログラムのひとまとまりの単位があって、それらが互いに連携し

て動作する様子を思い描いてみてください。

コンピュータは数十年前に世の中に登場してから目覚しい進歩を続けています。それと共に、コンピュータ

上で動くプログラムも複雑で大きなものになりつつあります。昔はコンピュータで行うことは算術演算がメイ

ンでしたが、今ではグラフィカルユーザーインターフェイスを備えた複雑なアプリケーションや、数十万人の

顧客データを扱うことを前提としたような大規模なシステムを開発する必要が生じています。Java はプログ

ラミング言語の歴史の中では比較的新しく誕生した言語で、このような複雑に込み入ったプログラムを複数の

開発者が役割分担しながら効率よく作成できるような工夫が随所に施されています。

そのため、まだプログラミングの経験がそれほど無い方が一人で小さなプログラムを作って練習をする上で

は、それほど必要とされない難しい概念も Java言語には含まれています。本書では、Javaでプログラミン

グを行う上で重要となる概念をできるだけわかりやすく解説することを心がけていますが、中には「プログラ

ミングの基本的な内容」と「大規模なプログラムを作るために必要な内容」の両方が含まれています。プログ

ラミングを始めたばかりの方は、最初から全てを理解しようとせずに、まずは「プログラミングの基本」に重

点を置いて学習するとよいでしょう。

Java言語のプログラミングをロボット作りにたとえた場合の関係を表1-1に示します。表の右側には本書

で対応している章番号を記しました。また、基本的な内容として習得すべきものには★★★を、大規模なプロ

グラムを作る上で役立つ内容には★を、その中間には★★をつけました。学習の際の際の参考としてください。

本書を読み進めていく上で表1-1を参考に、「何を学習しているのか」を意識するとよいでしょう。

表1-1 Javaプログラミングをロボット作りに喩えた場合の関係

ロボット作り Javaプログラミング

ロボットの動作スイッチを入れて動かす方法

を学ぶ

★★★ プログラムをコンパイルして実行する方法を学習す

る(1章と付録)

配線の仕方、ネジの締め方など、ロボットを作 ★★★ 変数の概念や、for文・if文などの構文を用いた基

Page 9: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

9

る上で必要となる基本的な技術を学ぶ 本的なコードの作成を学ぶ(2,3章)

予め準備されている部品を組み合わせる方法

を学ぶ

★★ クラスの概念を学ぶ(4章)

独自の部品を作成する方法を学ぶ ★★ 独自のクラスを作成する方法を学ぶ(4,5章)

たくさんの部品を効率的に作成、管理する方法

を学ぶ

★ 既存のクラスを拡張して新しいクラスを作成する方法を

学ぶ(6,7章)

既存の部品の仕様書の調べ方を学ぶ ★★ パッケージの扱いとAPI仕様書の見方を学ぶ(7章)

予想外のトラブルが発生した場合に備える方

法を学ぶ

★ 例外処理の概念と扱い方を学ぶ(8章)

主な部品の使用方法を学ぶ ★★ 主なクラスの使用方法を学ぶ(9,10,11章)

実際にロボットを作る上で役立つテクニック

を学ぶ

★★ イベント処理やスレッドの扱いなどを学ぶ(11章)

★↑上のロボット作りの喩えでわかりやすいイラストを入れていただけるとありがたいです★

■まとめ■

・Javaはオブジェクト指向型言語で、オブジェクトを組み合わせることでプログラムを作り上げていきます。

・Java を学習する際には、まず「プログラミングの基本的な内容」を理解してから「大規模なプログラムを

作るために必要な内容」を理解するようにしましょう。

練習問題

次の文章から誤っているものを選び、正しく直しましょう。

(1) コンピュータは人間が作成したプログラムコードを直接理解して処理を行う。

(2) Javaのプログラムコードを入力するときには大文字と小文字の違いが区別される。

(3) Javaは簡単なプログラムを作るための言語で、必要最低限の仕組みだけが準備された言語である。

(4) Javaではコンパイラとインタプリタという2つのソフトウェアによってプログラムコードが機械語

に翻訳される。

(5) Javaではコードをコンパイルすると、拡張子が.exeの実行可能ファイルが作成される。

Page 10: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

10

第 2 章 Javaの基本

2-1 画面へ文字を出力する

■ Javaのコードは基本的な記述方法が決まっています。画面に文字を出力することでプログラムの動作を

確認できます。

◆ Javaのコード

Javaの基本的なコードは次のような形式で記述します。

class クラス名 {

public static void main(String args[]) {

命令文

}

}

前章で紹介したExample1.javaも上の形式を満たしていますので見比べてみましょう。Example1.java

では、「クラス名」が「Example1」で、「命令文」が「System.out.println("はじめてのJavaプログラ

ム");」となっています。この命令文によって「はじめての Javaプログラム」という文字列が画面に表示さ

れたわけです。命令文以外の上下2行ずつについては4章以降で説明しますので、始めのうちは「Javaのコ

ードはこういうふうに記述するものだ」と思ってください。

命令文には複数の命令を含めることができます。

◆ 画面への出力

プログラミングを学習するには、実際にプログラムがどのように動作しているか見て確かめることが大切で

す。しかしコンピュータが内部で何を行っているかを実際に見ることはできませんから、何か処理を行ったと

きに、その結果を画面に表示させることでプログラムの動作を確認することがよく行われます。

画面に文字などを表示することを「出力」と言います。文字列などを出力するには、Example1.javaの例

のように、次のような命令文をコードに記述します。

System.out.println(出力したい内容);

「出力したい内容」の部分には"はじめてのJavaプログラム"のように、文字列の前後をダブルクォーテー

ション(")で囲みます。

何かの処理を行って、その結果を確認するには次のようなコードを作成することになります。

class クラス名 {

public static void main(String args[]) {

「処理1」を行う命令

System.out.println(処理1の結果を確認する内容);

「処理2」を行う命令

System.out.println(処理2の結果を確認する内容);

}

}

Javaでは

public static void main(String args[])

ここから処理が開始します

「クラス名」には好きな名前を指定できます

ここに実際にコンピュータが行う命令を記述します

Page 11: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

11

と書かれている行に続く中括弧の中({から}まで)を上から下へ向かって順番に処理します。上のコードで

は処理1を行い、その結果を確認する内容が画面に出力され、次に処理2を行い、処理2の結果が画面に出力

されます。

メモ System.out.println()は文字列を出力する命令で、括弧の中に出力したい文字列を指定します。

文字列は画面に改行付きで出力されます。この代わりにSystem.out.print()を使用すると、改行無しで文

字列が出力されます。

■まとめ■

・Javaのコードは記述の形式が決まっています。

・System.out.println(出力したい内容); という記述で文字列を画面に出力できます。

・プログラムはmainという単語が含まれる行から順に下に向かって命令が実行されます。

【コラム:エスケープシーケンス】

出力する文字列はダブルクォーテーションで前後を囲みますが、出力したい文字列にダブルクォーテーショ

ンが含まれる場合はどうすればよいでしょう。この場合は出力したいダブルクォーテーションの前に¥記号を

つけて¥"と入力します。「これは"実験"です」と出力したい場合には次のように記述します。

System.out.println("これは¥"実験¥"です");

このように¥記号と組み合わせて、特別な記号を表したものをエスケープシーケンスといいます。エスケープ

シーケンスには記号を表すものだけでなく、「改行」のような出力の仕方を制御するものもあります。

主なエスケープシーケンス

記号の組み合わせ 意味

¥' '

¥" "

¥¥ ¥

¥n (改行)

¥t (水平タブ)

¥r (キャリッジリターン)

2-2 変数

■ ある値を格納する入れ物を「変数」といいます。変数はプログラミングの中で最も大切な概念の1つです。

変数に値を格納する前に、格納する値の種類を指定して変数の宣言を行う必要があります。

◆変数とは

コンピュータが何かを計算するためには、計算に使用する値や結果などを一時的にどこかに記憶しておく必

要があります。この値を格納するための入れ物のことを変数といいます。変数はプログラミングの中で最も大

切な概念の1つです。

変数を使うには、変数の「名前」と「型」を決める必要があります。変数の名前は、例えばxやyのような

一文字の英字や、abcや a_123のように複数の英字と数字の組み合わせを使って自由に決めることができま

す。ただし、変数の名前を決める際には、次の点に注意する必要があります。

Page 12: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

12

・英字、数字、アンダースコア( _ )の組み合わせを使用できる

・先頭の文字が数字であってはいけない

・大文字と小文字が区別される

・Javaのプログラムで予め定められている特定のキーワードは使用できない(public, try, newなど)

型とは変数に格納できる値の種類のことで、Javaでは表2-1に示す8種類を使用できます。例えば、1や

-2のような整数値を格納するにはbyte、short、intの型のいずれかを使用します。1.2や-5.6のような

小数点を含む値を扱うためには、floatまたはdoubleの型を使用します。しかし、最初から表2-1の全て

の型を覚える必要はありません。最も一般的に用いられる、int と double、そして真偽値(真:true 又は

偽:false)を扱うためのbooleanの3種類をまずは覚えるようにしましょう。

表2-1 Javaでサポートされている型

型 格納できる値

char 16bit Unicode文字

boolean 真偽値:true(真) または false(偽)

byte 8bit 符号付整数 : -27(-128)~27-1(127)

short 16bit 符号付整数:-215(-32768)~215-1(32767)

int 32bit 符号付整数:

-231(-2147483648)~231-1(2147483647)

long 64bit 符号付整数

-263(-9223372036854775808)~263-1(9223372036854775807)

float 32bit 符号付浮動小数点数

double 64bit 符号付浮動小数点数

◆変数の宣言と代入

コードの中で変数を使用するには、次のような構文で変数を使う準備をします。このことを「変数を宣言す

る」といいます。

型名 変数名;

「型名」には表 2-1に記した型のいずれかを、「変数名」には任意の名前を指定します。型名と変数名の間

には空白を入れ、最後にセミコロン(;)つけます。

iという名前の変数にint型の値(整数値)を格納することを宣言するには次のように記述します。

int i;

abcという名前の変数にdouble型の値を格納することを宣言するには次のように記述します。

double abc;

上記のようにして変数を宣言すると、コンピュータの内部では値を格納するための入れ物が準備されます。

これ以降、宣言した変数に値を格納できるようになります。変数に値を格納することを値の代入といいます。

代入は次の構文で行えます。

変数名 = 値;

先ほどのように

int i;

と宣言した変数iに100を代入するには次のように記述します。

i = 100;

Page 13: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

13

これにより、iという名前の入れ物に100という値が格納されます(図2-1)。算数で習う等号( = )は左

辺と右辺が等しいことを意味しますが、Java 言語では左辺の変数に右辺の値を「代入する」ことを意味する

ので注意しましょう。

図2-1.「i」という名前のint型の変数に、100という値を代入する

それでは2-1節で学んだ画面へ文字列を出力する方法を使って、変数の宣言と代入を行った結果を確認して

みましょう。Example2_1.javaは、int型の変数iに100を代入する例です。

Example2_1.java

class Example2_1 {

public static void main(String args[]) {

int i;

i = 100;

System.out.println("iの値は" + i);

}

}

上のコードを実行すると

iの値は100

という文字列が画面に表示され、変数iに値100が格納されたことが確認できます。

上の例ではSystem.out.printlnで出力する文字列に

"iの値は" + i

と指定していますが、このように「+」演算子を使って文字列と整数を連結することができます。この例では、

"iの値は"という文字列と、変数iに格納されている値を表す文字列"100"が連結され"iの値は100"という

文字列が出力されます。

宣言と代入は一度に行うことも可能で、上のコードの

int i;

i = 100;

の2行は次のように1行で記述することもできます。

int i = 100;

どちらも同じ結果となります。

■まとめ■

・変数とは値を格納する入れ物のことです。

・変数を使うためには、「名前」と「型」を決める必要があります。

int型の入れ物

100

i

int型の変数iを宣言します

iに100を代入します

画面に「iの値は100」と出力します

Page 14: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

14

・変数を使用するには、まず型と名前をして「宣言」を行う必要があります。

・値を格納することを「代入」と言い、等号(=)を使用して左辺の変数に右辺の値を代入します。

2-3 算術演算子と式

■ 算術演算子を用いることで加減乗除などの演算を行えます。

Javaでは表2-2に示す算術演算子を使った式を扱えます。

表2-2 算術演算子

演算子 演算の内容 使用例 説明

+ 加算 a = 1 + 2 左辺と右辺を足し合わせます(aの値は3になります)

- 減算 a = 2 – 1 右辺から左辺を引き算します(aの値は1になります)

* 乗算 a = 2 * 3 右辺と左辺を掛け合わせます(aの値は6になります)

/ 除算 a = 4 / 2 右辺を左辺で割り算します(aの値は2になります)

% 剰余 a = 7 % 3 右辺を左辺で割った余りを求めます(aの値は1になります)

+= 加算代入 a += 2 左辺に右辺の値を足した値を代入します

(aの値は2増えます。a = a + 2 と同じです)

-= ☆減算代入 a -= 3 左辺から右辺の値を引いた値を代入します

(aの値は3減ります。a = a – 3 と同じです)

*= 乗算代入 a *= 2 左辺に右辺の値を掛けた値を代入します

(aの値は2倍になります。a = a * 2 と同じです)

/= 除算代入 a /= 3 左辺を右辺の値で割った値を代入します

(aの値は3分の1になります。a = a / 3 と同じです)

%= 剰余代入 a %= 2 左辺を右辺の値で割った余り代入します

(aの値は aを 2で割った余りになります。a = a % 2と同じで

す)

++ インクリメント a ++ 左辺の値を1増やします(a = a + 1 と同じです)

-- デクリメント a -- 左辺の値を1減らします(a = a - 1 と同じです)

次のようなコードでは、10+20を計算した値が変数iに代入されます。

int i;

i = 10 + 20;

メモ 式の中では空白と改行を自由に使えます。次の3つはどれも10+20の結果の30が変数iに代入され

ます。

i = 10 + 20;

i=10+20;

i =

10 +

20;

式の右辺に変数を含めることもできます。例えば、次のコードでは変数iに値10を代入し、変数jにはi

変数iに10を代入します

Page 15: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

15

の値(10)が代入され、変数kにはiに5を掛けた値(50)が代入されます。

int i = 10;

int j = i;

int k = i * 5;

式の右辺に左辺の変数を含めることもできます。次のコードでは変数 iに 10を代入し、その後で iに「i

に3を加算した値」を代入しています。つまりiには10+3の13が代入されます。

int i = 10;

i = i + 3;

上のコードの2行目の

i = i + 3;

は、表2-2にある加算代入の演算子を使って次のように記述することもできます。

i += 3;

値を1だけ増やす場合は

i = i + 1;

と記述してもよいですし、加算代入を使って

i += 1;

とすることもできます。また、プログラムでは値を1だけ増やしたり、1だけ減らすことが多く行われるので、

そのための特別な演算子として 1だけ増やすインクリメント演算子(++)、1だけ減らすデクリメント演算子

(--)が準備されています。それぞれ次のように使用します。

int i = 50;

int j = 50;

i ++;

j --;

■まとめ■

・ 算術演算子を使用することで、加減乗除の演算を行うことができます。

・ 加算代入演算子や減算代入演算子、インクリメント演算子やデクリメント演算子のように、通常の演算式の

記述を短くするための演算子もあります。

2-4 コメント

■ コードの中には、プログラムに影響を与えないメモを記述しておくことができます。

Javaではコードの中に//という記号があると、その行のそれ以降の文字がコンパイラに無視されます。コ

ンパイラに無視される文字はプログラムの動作にまったく影響を与えません。したがって、//の後には好きな

文字を記述することができます。一般にはプログラムの説明や、後で見たときに役立つメモを記述するのに使

用します。このような、プログラムに影響を与えない文章をコメントといいます。コメントをコードの中に記

述するには//という記号を使用するほかに/* */という記号も使用できます。/*と*/で囲まれた範囲がコメ

ント文として認識され、間に改行を入れて複数行のコメントを作成できます。

次のコードはExample2_1.javaにコメントを入れた例です。

i の値が1増えて51になります

jの値が1減って49になります

変数jにiの値を代入します

変数kにiの値に5を掛けた値を代入します

Page 16: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

16

Example2_1.javaにコメントを追加した例

/*

変数の宣言と代入を行うプログラム例

作成日:2005年4月1日

*/

class Example2_1 {

public static void main(String args[]) {

int i; // int型で名前がiの変数を宣言

i = 100; // iに100を代入

System.out.println("iの値は" + i); // iの値を出力

}

}

コンパイルした結果はコメントが無い場合とまったく変わりませんが、十分なコメントを記述しておくと、

後からコードを見たときに内容を素早く理解できるメリットがあります。

■まとめ■

・ // という記号の後ろから次の改行までの文字はコメント文になります。

・ /* と */ の記号で挟むことで、複数行のコメント文を記述することもできます。

2-5 型変換

■ 変数という値の入れ物は、型によって大きさが異なります。

◆変数の大きさ

変数は「値の入れ物」であると見なせ、その中に入れる値の種類を「型」と呼ぶことを2-2節で説明しまし

た。この型には表 2-2に示す種類があり、入れ物の大きさは型によって異なります(図 2-2)。そのため、代

入や演算を行うときに型の大きさに注意しなければならない場合があります。

数値を表す型(intやdouble)の入れ物の大きさは、大きい順に並べると次のようになります。

double > float > long > int > short > byte

図2-2.int型とdouble型では入れ物(変数)の大きさが異なる(double型の方が大きい)

型の大きさは普段あまり気にしなくても問題がありませんが、型が異なる変数どうしで代入や演算を行う場

合には注意が必要です。

int型の入れ物 double型の入れ物

1行のコメント文です。

複数行のコメント文です。あっても無くてもプ

ログラムの動作には影響を与えません

Page 17: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

17

◆異なる型の代入

型が異なる変数どうしで代入を行う場合には注意が必要と書きましたが、大きな型に小さな型の値を代入す

る場合は特に問題ありません。Example2_2.javaでは、小さな型(int)の値を大きな型(double)の変数に

代入しているので問題なくコンパイルと実行を行えます。

Example2_2.java

class Example2_2 {

public static void main(String args[]) {

int i = 10;

double d = i;

System.out.println("iの値は" + i );

System.out.println("dの値は" + d );

}

}

Example2_2.javaを実行した結果は次のようになります。iとdはどちらも同じ値を表しますが、iは整

数値なので10、dは小数点を含む値なので10.0と出力されます。

iの値は10

dの値は10.0

Example2_2.javaとは逆に、小さな型の変数に大きな型の値を代入しようとするとコンパイル時にエラー

が発生してしまいます。Example2_3.javaでは、大きな型(double)の値を小さな型(int)の変数に代入し

ているので問題となります。

Example2_3.java

class Example2_3 {

public static void main(String args[]) {

double d = 12.3;

int i = d;

// ↑上の行に問題がありコンパイルできません

System.out.println("dの値は" + d );

System.out.println("iの値は" + i );

}

}

この問題を回避するためには、大きな型を小さな型に強制的に変換することを明記する必要があります。具

体的には、Example2_3.javaの

int i = d;

の行を次のように書き換えます。

int i = (int)d;

このように、括弧の中に型名を記すことで、後に続く変数または式の値をカッコ内の型に変換することがで

きます。このことを型変換またはキャストといいます。

上記のように書き換えたプログラムは問題なくコンパイルでき、実行結果は次のようになります。

int型の変数iを宣言し、10を代入します

大きな型(double型)に小さな型の値を代入します

double型の変数dに値12.3を代入します

小さな型(int型)にdouble型の値を代入しようとしています

Page 18: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

18

dの値は12.3

iの値は12

iは整数値を格納する int型の変数なので、12.3の小数点以下が切り捨てられて 12が代入されたことが

わかります。型の大きな値を型変換によって型の小さな変数に代入する場合、このように値の精度が落ちるこ

とに注意する必要があります。

◆異なる型の演算

異なる型の変数どうしの演算を行った場合、最も大きいサイズの型に統一されて演算が行われます。例えば

int型とdouble型の値の足し算を行った場合、結果はdouble型となります。

同じ型の変数どうしの演算を行った場合、結果は元の変数と同じ型になります。これは一見すると特に問題

ないように思われますが、整数どうしの割り算を行ったときに意図した結果とならない場合があるので注意す

る必要があります。次のように

int a = 5;

int b = 2;

double c = a / b;

と記述した場合、cの値は2.5ではなく、2.0になってしまいます。これは、aとbが共に整数値を格納する

int型であるため、その2つを割り算した結果もint型になるためです。int型では2.5という小数点を含

む値は小数点以下を切り捨てた2という値になります。

正しい値をcに代入するには、int型のaとbの前に(double)をつけて、double型にキャストする必要

があります。

int a = 5;

int b = 2;

double c = (double)a / (double)b;

このようにすることで、cには2.5という正しい値が代入されます。

■まとめ■

・変数という値の入れ物は、型によって大きさが異なります。

・異なる型どうしの変数で演算を行うときには、サイズが大きい型に統一されます。

・型を明示的に変換することをキャストと言い、変数の前に(型名)をつけます。例:(double)i

2-6 配列

■ 配列は値を格納する入れ物が複数並んだものです。同じ型の変数を一度にたくさん扱う場合、配列を使

うと便利です。

◆1次元配列

同じ型の入れ物を1列に並べたものを1次元配列といいます。図2-3はint型の変数が5つ並んだ1次元

配列のイメージを表したものです。この5つの入れ物に、1つずつint型の値を格納することができます。こ

のような配列は、たとえば5つの都市の気温データをまとめて記録したい場合に使用できます。

int型の入れ物 int型の入れ物 int型の入れ物 int型の入れ物 int型の入れ物

Page 19: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

19

図2-3.配列のイメージ

配列を使用するには、その準備として次の2つの手順を行います。

1. 配列を表す変数を準備する(配列を宣言する)

2. 配列の要素の入れ物を準備する(配列の要素を割り当てる)

この手順は次の構文で行います。

型名 変数名[];

変数名 = new 型名[配列の大きさ];

場所ごとの平均気温(int型の値)を5個格納するための配列をtemperature(気温)という名前で作成

する場合には、次のように記述します。

int temperature[];

temperature = new int[5];

1行目でint型の配列を表すtemperatureという名前の変数を宣言しています。2行目で、5つ分の配列

の要素の割り当てを行っています。

上記の2行は、次のように1行にまとめることもできます。

int temperature[] = new int[5];

この1行の記述で、「配列の宣言」と「要素の割り当て」という2つの手順を行えます。

この例では、temperatureという名前の配列にint型の値を5個入れることができるので、次のような記

述で配列の各要素に値を代入できます。

temperature[0] = 24;

temperature[1] = 20;

temperature[2] = 16;

temperature[3] = 22;

temperature[4] = 23;

[]の中には、配列の何番目の要素にアクセスするかを示す数字(インデックス)を指定します。インデック

スは0から始ることに注意しましょう。上記の例のように配列の大きさが5の場合、0から4の値をインデッ

クスに指定できます。つまり、指定できるインデックスは 0 から「(配列の大きさ)-1」になります。範囲を

超えるインデックスを使用することはできないため、temperature[5]やtemperature[6]などは使用でき

ません。

上記の例では、配列の宣言をしてから要素を割り当て、その後に各要素に値を代入しました。これと同じこ

とを、次のように1行で記述することもできます。

型名 変数名[] = {値0, 値1, ... , 値n};

先ほど都市の気温の例は、次のように1行で記述できます。

int temperature[] = {24, 20, 16, 22, 23};

配列をプログラムの中で使用する場合、配列の大きさ(配列に幾つの要素が含まれているか)を知りたい場

合がでてきます。この場合、配列の名前に.length をつけることで、その配列に含まれる要素の数を知るこ

とができます。例えば

都市Aの気温が24度だということを記録します

都市Eの気温が23度だということを記録します

Page 20: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

20

int n = temperature.length;

と記述することで、配列temperatureの要素数(今回の例では5)を変数nに代入できます。

◆多次元配列

先ほどのように、一連の値を格納する配列を1次元配列といいます。Javaでは2次元またはそれ以上の多

次元配列を扱うことができます。2次元の配列とは、図2-3のように横に並んだ入れ物の列が、さらに縦にも

並んでいる様子をイメージするとよいでしょう。

都市の気温データが1つだけでなく、平均気温、最低気温、最高気温のように複数ある場合には、2次元配

列を使うと便利です。2次元配列の宣言と要素の割り当ては次のように記述します。

int temperature[][];

temperature = new int[5][3];

この記述で、3つの値を格納できる配列が5つ並んだ2次元配列を準備できます。

上の2行は次のように1行にまとめることもできます。

int temperature[][] = new temperature[5][3];

1 番目のインデックスで都市を指定し、2 番目のインデックスで気温の種類(平均、最低、最高)を指定す

ることで、5つの都市の3つの気温データを2次元配列に格納できます。

表2-3のようにして、気温の種類と都市の関係を2次元配列に定めた場合、都市Bの最高気温が23度であ

ることを、

temperature[1][2] = 23;

のようにして配列の要素に値を代入することができます。

表2-3. 都市と気温を格納する2次元配列

平均気温 最低気温 最高気温

都市A temperature[0][0] temperature[0][1] temperature[0][2]

都市B temperature[1][0] temperature[1][1] temperature[1][2]

都市C temperature[2][0] temperature[2][1] temperature[2][2]

都市D temperature[3][0] temperature[3][1] temperature[3][2]

都市E temperature[4][0] temperature[4][1] temperature[4][2]

多次元配列も1次元配列と同じように、1行で宣言と割り当てと代入を行うことができます。これは次のよ

うに記述します。

型名 変数名[] = {{値00, ... , 値0n}, {値10, ... , 値1n}, ... ,{値a0, ... , 値an}};

先ほどの都市と気温の関係を定めた2次元配列は次のように記述できます。

int temperature[][] = { {24, 22, 27}, {20, 17, 23}, {16, 11, 20},

{22, 18, 25}, {23, 20, 25} };

このように、Javaの多次元配列は「配列」の中に「配列」が入っていることがわかります。言い換えれば、

多次元配列とは配列の配列である、ということができます。

【コラム:いびつな多次元配列】

多次元配列は「配列」の中に「配列」を入れたものです。内側の配列は要素数が異なっても構いません。そ

のため、次のようなコードを記述することができます。

int array[][] = { {80},

{70, 65},

Page 21: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

21

{85, 55, 90, 85, 70}};

上記のように記述したときに、配列の中に入っている配列の数は次のようにして取得できます。

int n = array.length;

上の例では、配列が3つ入っているので、nの値は3になります。

内部の配列の要素の数は次のようにして取得できます。

int m = array[0].length;

内部の先頭の配列は要素数が1ですから、mの値は1になります。同様にして、array[1].lengthは2、

array[2].lengthは5となります。

実際のプログラムでは要素数の異なる多次元配列を扱うことはそれほどありません。理解が難しい場合は

「このようなものがある」ということを覚えて学習を先に進めましょう。

■まとめ■

・配列を使うことで、同じ型の複数の値をまとめて管理できます。

・配列を使うには、配列の宣言と要素の割り当ての2つの手順が必要です。

・配列の要素にはインデックスを用いてアクセスできます。

2-7 コマンドライン引数

■ コマンドライン引数を用いることで、実行時にプログラムへ文字列を渡すことができます。

◆コマンドライン引数とは

2つの整数の和を計算するプログラムを作りたいときに、1+1を計算するときと2+3を計算するとき、それぞ

れに専用のコードを作成してコンパイルするのでは大変です。2 つの整数の和を計算する機能だけをプログラ

ムし、実際に計算する値はプログラムを実行する時に指定できれば便利です。

Javaでは次のようにして、実行時に複数の文字列をプログラムに渡すことができます。

java 実行するクラス名 文字列1 文字列2 ... 文字列n

このように、実行するクラス名に続く 1つまたは複数の文字列をコマンドライン引数といいます。Javaの

プログラムは2-2節で学んだように

public static void main(String args[])

という記述に続く{}の中を順番に処理していきますが、このargsという名前の配列にコマンドライン引数で

指定した文字列が格納されています。

◆文字列の受け取り

次のExample2_4.javaはコマンドライン引数で渡された3つの文字列を出力するコードです。

Example2_4.java

class Example2_4 {

public static void main(String args[]) {

System.out.println("args[0]は" + args[0]);

System.out.println("args[1]は" + args[1]);

System.out.println("args[2]は" + args[2]);

}

コマンドライン引数の文字列がargsに格納されています

1番目の引数を出力します

2番目の引数を出力します

3番目の引数を出力します

Page 22: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

22

}

Example2_4.javaをコンパイル後、次のように実行すると、

java Example2_4 123 abcd 45_ef

画面には次のように出力されます。

args[0]は123

args[1]はabcd

args[2]は45_ef

実行時に指定したコマンドライン引数によって、画面へ出力される内容が変化します。

◆数値への変換

コマンドライン引数でプログラムに渡すことができるのは文字列です。そのため、引数を数値として足し算

や引き算を行うには、文字列を数値に変換する必要があります。

"123"のような文字列を、整数値を表すint型に変換するには次の構文を使用します。

Integer.parseInt(文字列)

"12.3"のような文字列を、小数点を含む数値を表すdouble型の値に変換するには次の構文を使用します。

Double.parseDouble(文字列)

Example2_5.java は、コマンドライン引数で渡された 2 つの数字を整数値に変換し、その合計を出力す

るプログラムです。

Example2_5.java

class Example2_5 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

int b = Integer.parseInt(args[1]);

int c = a + b;

System.out.println("合計" + c);

}

}

次のように、引数に"12"と"34"という2つの文字列を指定して実行すると、

java Example2_5 12 34

12+34は46なので、画面に次のように出力されます。

合計46

【コラム:コマンドライン引数を使用する際の注意】

Example2_5.javaは、コマンドライン引数で 2つの数字が渡されることを前提としたプログラムです。

もし、引数が無かったり、または1つだけだったりした場合、エラーが発生してしまいます。

また、渡された文字列が数値に変換できない文字列(例えば"abcd"のような英字)だった場合にもエラー

が発生します。このような問題への対処方法は8章で学習します。

■まとめ■

1番目の引数をint型に変換して変数aに代入します

2番目の引数をint型に変換して変数bに代入します

変数cにaとbを足した値を代入します

Page 23: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

23

・java コマンドでプログラムを実行するときに、コマンドライン引数として文字列をプログラムに渡すこ

とができます。

・プログラム側で、引数として渡される文字列をint型やdouble型に変換して、その値を使用できます。

練習問題

1. 次のようなコードを作成して3.2-2.1を計算しようとしましたが、コンパイルの時にエラーが発生し

ました。原因と対応策を考えてください。

class Practice2_1 {

public static void main(String args[]) {

x = 3.2 – 2.1;

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

}

}

2. 次の計算式を、加算代入(+=)、除算代入(-=)、乗算代入(*=)、除算代入(/=)、乗除代入(%=)、イン

クリメント(++)、デクリメント(--)の演算子を使って短い式に書き換えてください。

(1) a = a + 5 (2) b = b – 6 (3) c = c * a (4) d = d / 3 (5) e = e % 2 (6) f = f + 1 (7) g = g - 1

3. コマンドライン引数で渡された 2つの文字列を double型の数値に変換して、その 2つの積を出力す

るプログラムを作成してみましょう。

Page 24: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

24

第 3 章 プログラムの流れを制御する

3-1 処理の条件分岐

■ if文、if-else文を使用することで、条件によって実行する内容を切り替えることができます。

◆条件式と真偽値

ある条件を満たす場合と、そうでない場合で実行する内容を切り替えることを、処理の条件分岐といいます。

「条件を満たす」「条件を満たさない」の判断に用いる式を条件式といい、条件を満たす場合を真、満たさな

い場合を偽といいます。Javaではそれぞれをtrue(真)とfalse(偽)という単語で表現します。

メモ trueとfalseという2つの単語は今後も出てくる重要なものなので是非ここで覚えるようにしまし

ょう。

◆if文

次のようなif文を使うことで、条件を満たすときに実行される処理を記述できます。

if(条件式) {

命令文

}

上記の「条件式」が真(true)の場合だけ後ろの{}に囲まれた「命令文」が実行されます。「条件式」が偽

(false)の場合は「命令文」が実行されません。{}には複数の命令文を入れることもできます。

条件式は、一般に表3-2に示す関係演算子を使って2つの値を比較することを行います。その結果はtrue

(真)かfalse(偽)のどちらか一方になります。たとえば「左辺の値が右辺より大きい」ことを表す演算子

「>」を使った場合、「3>2」はtrueですが、「2>3」はfalseになります。

表3-2 関係演算子

演算子 説明

== 等しい

!= 等しくない

> より大きい

< より小さい

>= より大きいか等しい

<= より小さいか等しい

次のコードはif文を用いた例です。a>5がtrueの場合(aが5より大きい場合)だけ後の{}に記された

System.out.printlnの命令文が実行されます。a>5がfalseの場合(aが5より大きくない場合)は実

行されません。

if(a > 5) {

System.out.println("aの値は5より大きいです");

}

aの値が5より大きい場合だけ、中括弧の中の処理を行います

Page 25: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

25

◆if - else 文

if-else文は次のように記述し、条件に応じた処理の切り替えを行えます。

if(条件式) {

命令文1

} else {

命令文2

}

上記の「条件式」がtrueの場合は「命令文1」を実行し、「条件式」がfalseの場合は「命令文2」を実

行します。つまり、ifの後ろの命令文とelseの後ろの命令文のどちらか一方だけが実行されます。if文と

同様、{}には複数の命令文を入れることができます。

Example3_1.java は、この if - else 文を使用した例です。コマンドライン引数で指定した数値が 5

であるか否かを判定し、その結果を表す文字列を出力します。

Example3_1.java

class Example3_1 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

if(a == 5) {

System.out.println("引数の値は5です");

} else {

System.out.println("引数の値は5ではありません");

System.out.println("引数の値は" + a + "です");

}

}

}

Example3_1.javaをコンパイルしたプログラムを、次のように"5"を引数として実行すると、変数aには

5が代入されます。

java Example3_1 5

if文の条件式「a == 5」はtrueになるため、次のような文字列が出力されます。

引数の値は5です

次のように"4"を引数として実行した場合は、変数aには4が代入されます。

java Example3_1 4

if文の条件式「a == 5」はfalseになるため、elseの後の命令文が実行されて、次のような文字列が出力

されます。

引数の値は5ではありません

引数の値は4です

このように、引数に指定した値によって実行される処理を切り替えることができます。

コマンドライン引数で渡された文字列を整数(int

型)に変換して、変数aに代入します

aの値が5と等しいとき、評価式「a == 5」はtrueになります

評価式がtrueのときに実行されます

評価式が false のときに実

行されます

Page 26: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

26

【コラム:三項演算子】

実際のプログラムでは、評価式に応じて変数に代入する値を切り替えることがよくあります。次のコードは、

int型の変数a, bがあった場合に、大きいほうの値を変数cに代入する例です。

int c;

if(a > b) {

c = a;

} else {

c = b;

}

このような処理はよくあることなので、Java では「評価式の真偽に応じて値を切り替える」ための三項演

算子があります。これは次のように記述します。

評価式 ? 値1 : 値2

上の式は、「評価式」が真の場合「値1」となり偽の場合は「値2」となります。

この三項演算子を使用すると、上記のコードは次のように1行で簡潔に記述できます。

int c = (a > b) ? a : b;

三項演算子は扱いに慣れるとコードを短く記述できて便利です。しかし if-else文でも同じことが記述でき

るので、理解が難しい場合は最初の例のようにif-else文で記述できれば十分です。

◆複数のif-else文

if-else文は次のように連結して、複数の条件式に応じて処理の流れを分岐させることができます。

if(条件式1) {

命令文1

} else if(条件式2) {

命令文2

} else {

命令文3

}

上記の「条件式1」がtrueの場合は「命令文1」が実行されます。「条件式1」がfalseで「条件式2」が

trueの場合は「命令文2」が実行されます。「条件式1」も「条件式2」もfalseである場合だけ「命令文3」

が実行されます。このif - else 文の連結はいくつでも追加できます。

■まとめ■

・「条件を満たす」「条件を満たさない」の判断に用いる式を条件式といい、条件を満たす場合を真、満たさな

い場合を偽といいます。Javaではそれぞれをtrue(真)とfalse(偽)という単語で表現します。

・if文、if-else文を用いることで、条件式の真偽値に応じた処理の切り替えを行うことができます。

【コラム:if文の後のブロック】

if文の後の命令文が1つだけの場合、{}を省略することができます。

次の(a)と(b)のコードはどちらも内容は同じです。

(a)

if(a == 0)

aがbより大きいか評価します

aの値がbより大きくない場合、cにbの値を代入します

aの値がbより大きい場合、cにaの値を代入します

Page 27: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

27

System.out.println("a == 0 はtrueです");

(b)

if(a == 0) {

System.out.println("a == 0 はtrueです");

}

しかし、次の2つは異なる結果となります。

(c)

if(a == 0)

System.out.println("a == 0 はtrueです");

System.out.println("aの値は" + a);

(d)

if(a == 0) {

System.out.println("a == 0 はtrueです");

System.out.println("aの値は" + a);

}

(c)はif(a == 0)の後に{}が無いため、その後に続く1つの命令だけが条件式によって実行の有無が切り

替わります。その後の命令文は条件式の真偽によらず必ず実行されます。

(d)は条件式によって{}の中の2つの処理の実行の有無が切り替わります。

{}の無いif文は(c)の例のように条件式の影響が及ぶ命令と及ばない命令が見分け難いことがあるので、命

令が1つの場合でもif文の後は{}で囲むようにするとよいでしょう。

3-2 コードのブロックとインデント

■ コード全体はブロックという単位の集合で構成されます。各行の先頭に適切な空白を入れると、ブロック

の範囲がわかりやすくなります。

if文やif-else文では、条件に応じて行う命令文を{}で囲みました。このように中括弧で囲まれた範囲を

コードのブロックと言います。中括弧の開き({)と閉じ(})は必ず1対1の対応があり、それによって1つの

ブロックが定義されます。ブロックの中には、さらにブロックを入れることができ、Java のプログラムはこ

のようなブロックを複数使用して記述されます。

次のコードは既に例として扱った Example3_1.java ですが、図に示すように外側から順に

(a),(b),(c1),(c2)の4つのブロックが存在します。

class Example3_1 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

if(a == 5) {

System.out.println("引数の値は5です");

} else {

System.out.println("引数の値は5ではありません");

System.out.println("引数の値は" + a + "でした");

(c1)

(c2)

(b) (a)

aが0の時だけ実行されます

aが0の時だけ実行されます

aの値によらず必ず実行されます

Page 28: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

28

}

}

}

それぞれのブロックは、次のような役割を持っています。

(a) class Example3_1 { ~ } : クラスの定義を行うブロックです。クラスについては4章で学習し

ます。

(b) public static void main(String args[]) { ~ } : クラスのメソッドを定義するブロック

です。このmainメソッドはプログラムが実行される時に最初に処理される特別なメソッドです。メソ

ッドについては4章で学習します。

(c1) if(a == 5) { ~ } : aの値が5であるときに行われる処理を定義するブロックです。

(c2) else { } : aの値が5でなかったときに行われる処理を定義するブロックです。

Example3_1.javaでは、最も外側のブロック(a)、その中の(b)、さらにその中の(c1)と(c2)、という

ようにブロックが3階層になっています。各ブロックの中で宣言した変数は、そのブロックの中でのみ使用す

ることができます。もしブロック(c1)の中で宣言された変数があった場合、その変数はブロック(c2)で使用

することはできません。3行目で宣言されている変数 aは、ブロック(b)の中で宣言されているので、その内

側のブロックでも使用できます。このように、変数の扱える範囲をスコープと言います。変数のスコープは、

変数の宣言が行われたブロックの中に限定されます。

ところで、Java のプログラムではコードの中に行頭の空白があっても無くても違いは無いのですが、ブロ

ックの階層を理解しやすくするために、階層が深いものほど行頭に空白を多く入れることが一般的です。この

ように、ブロックの階層を理解しやすくするための空白をインデントといいます。インデントがあると、後か

らコードを見たときに処理の内容を理解しやすいという利点があります。本書で紹介するコードも、ブロック

の階層がわかりやすいようにインデントを付けています。

■まとめ■

・ Javaのコードには複数のブロックが含まれ、それらは階層構造を持っています。

・ 行の先頭に空白(インデント)を入れるとコードが見やすくなります。

・ 変数には、その変数を扱える範囲(スコープ)があります。

【コラム:インデントと改行の入れ方】

プログラムが複雑になりブロックが何層にも入り組んでくると、コードを見ても処理の内容を理解するのが

難しくなってきます。そのため、ブロックの階層に応じたインデント(行頭の空白)を入れて、少しでもコー

ドが見やすくなるように心がけましょう。また、適切な箇所に改行を入れることも重要です。インデントや改

行の入れ方には特に明確な決まりがあるわけではありませんので、個人の自由なスタイルで構いません。主な

インデントと改行の入れ方には次の2通りがあります。

(a) 開き括弧({)を行末に配置する方法

class Example3_1 {

public static void main(String args[]) {

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

}

}

Page 29: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

29

(b) 開き括弧({)を行頭に配置する方法

class Example3_1

{

public static void main(String args[])

{

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

}

}

(b)のスタイルの方がブロックの始まりと終わりの対応がわかりやすい、というメリットがありますが、改行

が多い分、一度に見られるコードの量が少なくなってしまうデメリットもあります。本書では紙幅の関係から、

改行の少ない(a)のスタイルを使用しています。

3-2処理の繰り返し

■ コンピュータで何かの計算を行う場合、同じ処理の繰り返しが必要なことが多くあります。このような場合、

同じ処理を繰り返すためのループ構文を使用すると簡単に記述できます。Javaにはfor文、while文、do -

while文の3種類のループ構文があります。

◆for文

for文は次のように記述し、同じ命令を指定回数行うことができます。

for(初期化処理; 繰り返しを継続する条件式; 次の繰り返しに移る時に行う処理) {

繰り返す処理

}

for文では、まず「初期化処理」が実行され、「繰り返しを継続する条件式」がtrueである限り{}内の「繰

り返す処理」が実行されます。続いて「次の繰り返しに移るときに行う処理」が実行され、再び「繰り返しを

継続する条件式」がtrueであるか評価されます。

Example3_2.javaは、for文を使用した例です。上記のfor文の記述方法と見比べてみましょう。

Example3_2.java

class Example3_2 {

public static void main(String args[]) {

for(int i = 0; i < 5; i++) {

System.out.println("forループ内の処理です");

}

}

}

for文の初期化処理として、int型の変数 iを宣言して iに 0を代入しています。繰り返しを継続する条

件は「iが5より小さい」ことです。そして、次の繰り返しに移るときにiの値を1つ大きくしています。つ

まり、iの値は 0から 1つずつ増えて 4になるときまで(i < 5 が trueなため)繰り返し処理を行い、i

の値が5になった時点で(i < 5 がfalseになるため)繰り返しを終了します。

「iの値を 0から 1つずつ増やし、5より小さい

間は処理を続ける」ということを意味します。

ループします

Page 30: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

30

Example3_2.javaを実行した結果は次のようになります。

forループ内の処理です

forループ内の処理です

forループ内の処理です

forループ内の処理です

forループ内の処理です

コードの中のforループ内に記述された

System.out.println("forループ内の処理です");

という命令が5回繰り返されたことがわかります。

◆for文内で変数を使う

Example3_2.java ではfor文の初期化で

int i = 0;

というように変数iを宣言しています。この場合、for文のブロック内でこの変数iを使用できます。

Example3_3.javaはforループによってiの値を1から10まで変化させながら、変数sumにiの値を

足し合わせています。sumには1から10までの値を足し合わせた結果が代入され、最後にその結果を出力し

ています。

Example3_3.java

class Example3_3 {

public static void main(String args[]) {

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum += i;

System.out.println("変数sumに" + i + "を加えました");

}

System.out.println("変数sumの値は" + sum + "です");

}

}

Example3_3.javaの実行結果は次のようになります。

変数sumに1を加えました

変数sumに2を加えました

変数sumに3を加えました

変数sumに4を加えました

変数sumに5を加えました

変数sumに6を加えました

変数sumに7を加えました

変数sumに8を加えました

変数sumに9を加えました

変数sumを宣言し、0を代入します

sumにiの値を足します

iの値を1から10ま

で増やしながら繰り

返します

sumの値を出力します

ループします

Page 31: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

31

変数sumに10を加えました

変数sumの値は55です

メモ 文字列と文字列は「+」演算子で連結できます。例えば「"こんにちは" + "Java"」は"こんにちはJava"

という文字列になります。この「+」は算術演算子の「足し算」とは違って、文字をつなげる働きをもって

いることに注意しましょう。文字列と文字列だけでなく、文字列と変数を「+」でつなげた場合、今まで見

てきた例のように、「"iの値は" + i」という記述で、文字列の後ろに変数の値を文字列にしたもの(iの

値が100だった場合には"100"という文字列)をつなげられます。これと同じように、Example3_4.java

"変数sumに" + i + "を加えました"

という記述は、i の値を文字列にしたものが"変数 sum に"と"を加えました"の間に連結されます。iの値

が1の場合には"変数sumに1を加えました"という文字列になります。

◆while文

while文は次のように記述し、同じ命令を特定の条件が成り立つ間だけ処理を繰り返し行います。

while(繰り返しを継続する条件式) {

繰り返す処理

}

まず「繰り返しを継続する条件式」の真偽値が評価され、これがtrueであれば{}内の「繰り返す処理」が

実行されます。その後、再び「繰り返しを継続する条件式」が評価され、falseであれば繰り返しを終わりま

す。

Example3_4.javaは、while文を使用した例です。上記のwhile文の記述方法と見比べてみましょう。

Example3_4.java

class Example3_4 {

public static void main(String args[]) {

int i = 5;

while(i > 0) {

System.out.println(i);

i--;

}

}

}

まず、while文の前に変数iを宣言してiに5を代入しています。続いてwhile文により「iが0より大

きい」という条件を満たす間は、それに続く{}内の処理を繰り返します。この処理は「iの値を画面に出力し、

その後でiの値を1小さくする」というものです。これにより、iの値は5から1つずつ小さくなり、0にな

った時点でi > 0というwhile文の条件式を満たさなくなる(falseになる)のでループを抜けます。

Example3_5.javaを実行した結果は次のようになります。

5

4

3

変数iを宣言し、5を代入します

iの値を1減らします

iが0より大きいか評価し、大きい場合は{}の中の処理を行います

ループします

Page 32: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

32

2

1

◆do - while文

do - while文は次のように記述し、whileと同様に同じ命令を特定の条件の間だけ繰り返し行います。

do {

繰り返す処理

} while(繰り返しを継続する条件式);

while文と似ていますが、最初に処理を行ってから、その後で「繰り返しを継続する条件式」が評価される

点が異なります。つまり、{}内の処理は条件式によらず必ず1回は行われるという特徴があります。

Example3_5.javaは、do - while文を使用した例です。上記のdo - while文の記述方法と見比べて

みましょう。

Example3_5.java

class Example3_5 {

public static void main(String args[]) {

int i = 5;

do {

System.out.println(i);

i--;

} while(i > 0);

}

}

Example3_5.javaは while文を用いた Example3_4.javaの例と同じ処理を行います。最初に変数 i

を宣言してiに5を代入しています。続いてdo - while文により「iの値を画面に出力し、その後でiの

値を1小さくする」ということを行います。その後、「iが0より大きい」という条件を満たす間は、doに続

く{}内の処理を繰り返します。これにより、iの値は 5から 1つずつ小さくなり、0になった時点で while

文の条件式を満たさなくなる(falseになる)のでループを抜けます。

このように、同じ処理をwhile文でもdo – while文でも記述することができます。ただし、do – while

文は条件式の評価は最初に 1 回めの処理を行った後なので、i の値がはじめから 0 であった場合、

Example3_4.javaでは1回も処理が行われませんが、Example3_5.javaでは1回だけ処理が行われると

いう違いがあります。

Example3_5.javaを実行した結果は次のようになります。

5

4

3

2

1

■まとめ■

・ 同じ処理を繰り返すにはループ構文を使用します。

変数iを宣言し、5を代入します

iの値を1減らします

iが0より大きいか評価し、大きい場合はdo{}の中の処理を行います

ループします

Page 33: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

33

・ ループ構文にはfor文、while文、do-while文の3種類があります。

3-3 ループ処理の流れの変更

■ 特定のキーワードを使って、ループ処理を途中で抜け出したり、ループの中の残りの処理をスキップさせる

ことができます。

◆break文

前節で挙げたループ処理の例では、条件式を満たさなくなった時点で繰り返し処理を終了しました。このブ

ロックの中で

break;

と記述すると、条件式の評価を行わずにループ処理を強制的に抜けることができます。

たとえば、Example3_7.javaは Example3_4.javaと同じように 1から順に値を sumに加算していま

すが、この合計値が20を越えた時点でbreakによってループを抜けています。

Example3_6.java

class Example3_6 {

public static void main(String args[]) {

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum += i;

System.out.println("変数sumに" + i + "を加えました。sumは" + sum);

if(sum > 20) {

System.out.println("合計が20を超えました。");

break;

}

}

}

}

実行結果は次のようになります。for文ではiが1から10までの間ループを繰り返すように記述されてい

ますが、合計値が 20を越えた時点(iの値が 6になった時点)で繰り返し処理が終了したことを確認できま

す。

変数sumに1を加えました。sumは1

変数sumに2を加えました。sumは3

変数sumに3を加えました。sumは6

変数sumに4を加えました。sumは10

変数sumに5を加えました。sumは15

変数sumに6を加えました。sumは21

合計が20を超えました。

◆continue文

ループ処理の流れを変更する方法として、breakと対になるのがcontinueです。次のように記述すると、

Example3_4 に対して

新しく追加された箇所

です。sumの値が20を

超えたらループを強制

的に抜けます。

Page 34: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

34

ブロックの中の残りの処理をスキップして、次の繰り返しに移らせることができます。

continue;

Example3_7.javaはcontinueを使用した例です。for文によって1から10の値をsumに加算してい

ますが

i % 2 == 0

の条件式が真の場合はcontinueによって残りの処理がスキップされます。

%は剰余を求める演算子(2-5節参照)ですから「i % 2」はiを2で割った余りを表します。この値がゼ

ロの場合、上の条件式がtrueになります。つまりiの値が2で割り切れる(iが偶数である)場合はそれ以

降の

sum += i;

System.out.println("変数sumに" + i + "を加えました。sumは" + sum);

の2行がスキップされ、次の繰り返し処理に移ることになります。

Example3_7.java

class Example3_7 {

public static void main(String args[]) {

int sum = 0;

for(int i = 1; i <= 10; i++) {

if(i % 2 == 0) {

continue;

}

sum += i;

System.out.println("変数sumに" + i + "を加えました。sumは" + sum);

}

}

}

実行結果は次のようになります。for文ではiが1から10までの間ループを繰り返すように記述されてい

ますが、偶数の場合はsumにiを加算する処理がスキップされていることが確認できます。

変数sumに1を加えました。sumは1

変数sumに3を加えました。sumは4

変数sumに5を加えました。sumは9

変数sumに7を加えました。sumは16

変数sumに9を加えました。sumは25

■まとめ■

・ breakを使用すると、条件式の評価を行わずにループ処理を強制的に抜けることができます。

・ continueを使用すると、残りの処理をスキップして次の繰り返しに移らせることができます。

3-4 ループのネスト

■ 今まで学習したfor文とwhile文、do – while文は、ループの中にループを入れることができます。

i % 2 == 0 が true の場合、以降の処理をスキップし

て次の繰り返し処理に移ります。

Page 35: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

35

あるループが別のループに含まれることをネストといいます。

Example3_8.javaでは、aの値を1から3まで増やしながら処理を繰り返すforループの中に、bの値

を1から3まで増やしながら処理を繰り返す別のforループが含まれています。

Example3_8.java

class Example3_8 {

public static void main(String args[]) {

for(int a = 1; a <= 3; a++) {

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

for(int b = 1; b <= 3; b++) {

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

}

}

}

}

Example3_8.javaを実行した結果は次のようになります。外側のループの処理(aの値を 1から 3まで

増やす処理)の中に内側のループの処理(bの値を1から3まで増やす処理)が含まれていることが確認でき

ます。

a = 1

b = 1

b = 2

b = 3

a = 2

b = 1

b = 2

b = 3

a = 3

b = 1

b = 2

b = 3

■まとめ■

・ ループ文の中にループ文を入れることができます。これをループのネストと言います。

3-5 処理の場合分け

■ 変数の値によって処理を場合分けする場合、switch文を用いると便利です。

条件に応じて処理の内容を場合分けするには、3-1節で記したようにif-else文を連結する方法が使えます

内側のループ 外側のループ

内側のループ

内側のループ

内側のループ

外側のループ

Page 36: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

36

が、条件式が(a == 1)のように変数が特定の整数値に一致するかどうかの評価である場合、次のようなswitch

文を使うことで、コードを簡潔に記述できます。

switch(式) {

case 値1:

命令文1

break;

case 値2:

命令文2

break;

case 値3:

命令文3

break;

default:

命令文4

}

switch文では「式」の値が caseの後に記された値と等しい場合、その後に続く処理を break;が現れる

まで続けます。上記の構文では、「式」の値が「値 1」と等しい場合には「命令文 1」が、「値 2」と等しい場

合には「命令文2」が、「値3」と等しい場合には「命令文3」が実行されます。それ以外の場合は「default:」

以降に記された「命令文4」が実行されます。

「式」には「i - 5」のような演算式や「i」のような変数そのものを用いることができます。ただし、こ

れらは整数である必要があります。

Example3_9.javaは、コマンドライン引数(2-9節参照)の値によって処理を切り替える例です。変数a

の値が0の場合はcase 0:に続く行が実行され、1の場合にはcase 1:に続く行、それ以外はdefault:に

続く行が実行されます。

Example3_9.java

class Example3_9 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

switch (a) {

case 0:

System.out.println("0が入力されました");

break;

case 1:

System.out.println("1が入力されました");

break;

default:

System.out.println("0と1以外が入力されました");

}

}

}

switchブロックの始まり

switchブロックの終わり

switchブロックを抜けます

switchブロックを抜けます

switchブロックを抜けます

「式」の値が「値1」と等しい場合、これ以降の命令が実行されます

「式」の値が「値2」と等しい場合、これ以降の命令が実行されます

「式」の値が「値3」と等しい場合、これ以降の命令が実行されます

「式」の値が「値1」~「値3」と等しくない場合、これ以降の命令が実行されます

1番目の引数をint型に変換して変数aに代入します

変数aの値によって処理の場合わけを行います

aが0の場合、これ以降の命令が実行されます

aが1の場合、これ以降の命令が実行されます

aが0でも1でもない場合、これ以降の命令が実行されます

switchブロックを抜けます

switchブロックを抜けます

Page 37: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

37

switch文ではbreak;が現れるまで処理が続けられるので、次のようにswitch文を記述するとaの値が

0の時と1の時で同じ実行結果となります。

switch (a) {

case 0:

case 1:

System.out.println("0または1が入力されました");

break;

default:

System.out.println("0と1以外が入力されました");

break;

}

■まとめ■

・switch文を用いることで、式の値に応じた処理の場合わけを簡潔に記述できます。

・switch文では、caseキーワードによって値に応じた処理の開始点を切り替えることでき、breakでブロ

ックを抜けます。

3-6 論理演算子

■ 論理演算子を用いることで、複数の条件の組み合わせを表現できます。

if文やfor文などで用いる条件式で、「aが10であること」を条件にするには

a == 10

と記述することができました。この条件式を「aが10であり、かつbが5であること」や「aが10である、

または bが 5であること」というように、複数の条件を組み合わせて作成するには、表 3-3に示す論理演算

子を使用します。

表3-3 論理演算子

演算子 動作 式がtrueになる条件 使用例

&& 論理積 左辺と右辺の両方が

trueのとき

a > 0 && b < 0

(a が0より大きく、かつbが0より小さい場合にtrue)

|| 論理和 少なくとも左辺と右辺

のどちらかがtrueの

とき

a > 0 || b < 0

(a が0より大きい、またはbが0より小さい場合にtrue)

^ 排他的論

理和

左辺と右辺のどちらか

が true で他方が

falseのとき

a > 0 ^ b < 0

(a が0より大きく、かつbが0より小さくない場合、もし

くは a が 0 より大きくなく、かつ b が 0 より小さい場合に

true)

! 否定 右辺が false のとき

(左辺は無し)

!(a > 0)

(aが0より大きくない場合にtrue)

論理演算子を使用することで、「aが10であり、かつbが 5であること」は「a == 10 && b == 5」と

記述できます。また「aが10である、またはbが5であること」は「a == 10 || b == 5」と記述できま

aが0の場合、これ以降の命令が実行されます

aが1の場合、これ以降の命令が実行されます

switchブロックを抜けます

Page 38: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

38

す。

■まとめ■

・ 左辺と右辺の両方が真であることを条件にするには、論理積(&&)を使用します。

・ 左辺と右辺の少なくとも一方が真であることを条件にするには、論理和(||)を使用します。

・ 左辺と右辺の一方が真で他方が偽であることを条件にするには、排他的論理和(^)を使用します。

・ 右辺が偽であることを条件にするには、否定(!)を使用します。

【コラム:演算子の優先順位】

Javaでは算術演算子の方が関係演算子よりも高い優先順位を持ちます。

a + 10 > b * 5

という条件式があった場合、算術演算子(この例では+と*)の方が関係演算子(この例では>)よりも優先され、

(a + 10)という値と(b * 5)という値が計算されてから、その大小が比較されます。式の中の一部を括弧()

で囲うと、括弧の中が優先されます。したがって、次の記述方法でも上で記述したものと同じ意味を持ちます。

(a + 10) > (b * 5)

コードの見易さという観点からは、このように括弧で右辺と左辺を囲んだ方が処理の内容を理解しやすいでし

ょう。

関係演算子と論理演算子には、次のような優先順位があります。

優先順位 演算子

高い

低い

!

>, >=, <, <=

==, !=

&&

||

関係演算子(>と<)と論理演算子(&&)では関係演算子の方が優先順位が高いので

a > 10 && b < 3

という条件式は(a > 10)という条件式と(b < 3)という条件式の論理和になります。

これも括弧を使用して

(a > 10) && (b < 3)

と記述した方がわかりやすいでしょう。

練習問題

1. 次の条件を関係演算子を使って表現してみましょう。例:aはbより大きい → a > b

(1) a は b と等しい

(2) a は b と等しくない

(3) b は c より小さい

(4) a は b 以下である

(5) c は b 以上である

2. コマンドライン引数で渡された文字列を整数に変換して変数 aに代入するプログラムを次のように作成し

ました。[空欄]に aの値が偶数の時には"偶数です"、奇数の時には"奇数です"と表示するコードを追加して

Page 39: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

39

ください。

class Practice3_2 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

[空欄]

}

}

3. 10 から 20 までの和(10 + 11 + ... + 20)を計算して結果を出力するプログラムを作りましょう。

for文を使った場合と、while文を使った場合の2つ作成してみましょう。

4. 次のようなswitch文があったとき、iの値が1,2,3,4,5のとき、それぞれどのような出力結果が得ら

れるか予測しましょう。

switch(i) {

case 1:

System.out.println("A");

case 2:

break;

case 3:

System.out.println("B");

case 4:

default:

System.out.println("C");

}

5. 次の条件を関係演算子を使って表現してみましょう。

例:aはbより大きく、cはdより小さい → (a > b) && (c < d)

(1) aは5または8と等しい

(2) aとcは共にb以下

(3) aは1より大きく10より小さいが5ではない

(4) aはbまたはcと等しいがaとdは等しくない

Page 40: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

40

第 4 章 クラスとメソッド

4-1 クラスとは

■ Java言語はオブジェクト指向の言語であり、オブジェクトの組み合わせでプログラムが動作します。クラ

スはオブジェクト(部品)の雛形と考えることができ、Java言語を学習する上で最も重要な概念です。

Java 言語はオブジェクト指向型言語で、オブジェクトを組み合わせることで複雑なプログラムを作ってい

きます。オブジェクトとは聞きなれない単語かもしれませんが、プログラムの「部品」だと考えることができ

ます。部品を組み合わせることでプログラムが作成されます。この部品の属性や機能を定義したものがクラス

です。

クラスをJava言語で定義するには次のように記述します。

class クラス名 {

クラスの属性

クラスの機能

}

クラスの属性には既に学習した「変数」を定義できます。クラスの機能にはこれから本章で学習する「メソ

ッド」と次章で学習する「コンストラクタ」を定義できます。これらをまとめて、クラスのメンバと呼びます。

実は今まで例題として見てきたコードも上に示したクラスの定義に従った形をしていました。次のコードは

1章に登場した最初のプログラムExample1.javaです。

Example1.java

class Example1 {

public static void main(String args[]) {

System.out.println("はじめてのJavaプログラム");

}

}

Java でのプログラミングとは、クラスを作成することだということを確認できます。この例では、名前が

Example1というクラスを定義しています。クラスの機能として

public static void main(String args[]) {

System.out.println("はじめてのJavaプログラム");

}

の3行が記述されています。

つまり、Example1.javaでは、上記の 3行で記された内容を実行するための Example1という名前のク

ラスを定義したことになります。Example1.javaをコンパイルすると、Example1.classというクラスフ

ァイルが作られます。

このように、Javaでのプログラミングとはクラスを定義することである、と言い換えることができます。

今までの例題ではクラスを 1つだけ作成して、そのクラスに定義された命令を実行してきました。Javaの

プログラムでは、複雑な機能を実現するためには複数のクラスを組み合わせることを行います。本章では簡単

なクラスを1つ作成し、それを他のクラスから利用する方法(つまり2つのクラスを使用してプログラムを動

作させる方法)を学びます。

クラスの定義の始まり

クラスの定義の終わり

Page 41: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

41

■まとめ■

・ クラスは、オブジェクトの属性(変数)や機能(メソッド)を定義したものです。

・ Javaのプログラミングはクラスを作成することだと見なすことができます。今までの例題で見てきた全て

のプログラムで、クラスが定義されています。

4-2 クラスの定義とオブジェクトの作成☆

■ 新しいクラスを定義し、そのクラスのオブジェクトを作成します。

クラスはJavaのプログラムの基本となるものです。今までもExample○_○というクラスをいくつか見て

きました。

4-1節のクラスの定義に従えば、中身の無い最も単純なクラスは次のようにして作成できます。

class SimpleClass {

}

このコードはクラスを定義する構文の形を満たしているので、コンパイルするとSimpleClass.classと

いう名前のクラスファイルが作られます。

しかし、中身の無いクラスでは何もできないので、クラスに新しい定義を追加してみましょう。

単純な例として、何かの値を属性として持つクラスを作成してみます。たとえば、double型の変数xとy

を属性に持つPointという名前のクラスは次のように記述できます。

Point.java(1)

class Point {

double x;

double y;

}

上記のコードをPoint.javaという名前で保存し、コンパイルするとPoint.classというファイルが作

成できます。

メモ クラスの名前は変数の名前と同じように英字と数字の組み合わせで好きな名前を使用できますが、先頭

の文字は大文字にするのが慣例になっています。

続いて、このPointクラスを使用するプログラムの作り方を見ていきましょう。

クラスはオブジェクトの属性や機能を定義したものであり、オブジェクトの雛形と見なすことができます。

この「オブジェクトの雛形」から実際にオブジェクトを作成し、プログラムで使用するには次の2つの手順が

必要です。

(1) オブジェクトを扱う変数を宣言する

(2) new演算子を用いてオブジェクトを作成し、変数に代入する

それぞれ次のように記述します。

(1)

クラス名 変数名;

(2)

Pointという名前のクラスの定義が始まります

Pointという名前のクラスの定義を終わります

xとyという名前の変数をクラスの属性として定義します

Page 42: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

42

変数名 = new クラス名();

(1)は今までに学習した変数の宣言と同じ形です。クラス名を変数の型と見なすことができます。続いて(2)

のように new演算子を用いてオブジェクトを作成し、変数に代入します。これは 2-8節で学習した配列要素

の割り当てと似ています。

具体例として、先ほどの Pointクラスのオブジェクトを作成して、それを変数 pに代入するには次のよう

に記述します。

Point p;

p = new Point();

この2行は次のように1行にまとめることができます。

Point p = new Point();

このようにnew演算子を使って作成されたオブジェクト(上記のp)はインスタンスとも呼ばれます。イン

スタンスに含まれる変数(Pointクラスの例ではxとy)はインスタンス変数といい、次のように記述してア

クセスできます。

オブジェクト名.インスタンス変数名

例えば、Pointクラスのオブジェクトpの変数xにアクセスするには

p.x

と記述します。

次のExample4_1.javaはPointクラスのオブジェクトを実際に作成して利用するコードの例です。はじ

めにPointクラスのオブジェクトを作成し、インスタンス変数に値を代入しています。

Example4_1.java

class Example4_1 {

public static void main(String args[]) {

Point p = new Point();

p.x = 1.2;

p.y = 2.3;

System.out.println("p.x = " + p.x);

System.out.println("p.y = " + p.y);

}

}

メモ Example4_1.javaはPointクラスを使用しています。そのため、Example4_1.javaをコンパイ

ルするには、事前にPoint.classがExample4_1.javaと同じディレクトリに存在する必要があります。

まずはPointクラスを定義するPoint.javaという名前のファイルを作成してコンパイルしておきましょう。

■まとめ■

・オブジェクトを生成するには、new演算子を使用します。このオブジェクトのことをインスタンスともいい

ます。

・オブジェクトのインスタンス変数にアクセスするには、オブジェクト名の後ろにドット(.)を記し、続けて

変数名を記述します。

Pointクラスのオブジェクトを作成して、変数pに代入します

pの持つ変数xに1.2を代入します

pの持つ変数yに2.3を代入します

pの持つ変数xの値を出力します

pの持つ変数yの値を出力します

Page 43: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

43

4-3 参照

■ オブジェクトを表す変数は、オブジェクトそのものを格納するのではなく、オブジェクトがどこにあるかを

表す情報を格納します。これを「参照」といいます。

2-3節では「変数」を「値を入れる入れ物」にたとえて説明しました。ところが「入れ物」として考えるこ

とができるのは表2-1に示した基本的な型を表す変数だけで、それ以外のオブジェクトを表す変数(たとえば

前節のPointクラスのオブジェクトを表す変数p)は、オブジェクトそのものを格納する入れ物ではありませ

ん。Javaでは、intやdoubleような基本的な型以外の変数はオブジェクトの「参照」を保持します。参照

とはオブジェクトがある場所を示す「住所メモ」にたとえることができます。

前節のExample4_1.javaの例を図に表すと図4-1のようになります。変数pには、オブジェクトそのも

のが格納されるわけではなく、オブジェクトのある「住所」の情報が格納されます(図中「○○番地」と示し

た具体的な住所はコンピュータが内部的に決定し、私たちが直接知ることはできません)。図の例では p は

Pointクラスのオブジェクトを参照するといいます。

図4-1. Point型の変数pが、Pointクラスのオブジェクトの参照を格納する様子

次のExample4_2.javaは参照の仕組みを理解するための例です。

Example4_2.java

class Example4_2 {

public static void main(String args[]) {

Point p1 = new Point();

Point p2 = new Point();

Point p3 = p2;

p1.x = 1.2;

p1.y = 2.3;

p2.x = 9.8;

p2.y = -8.7;

System.out.println("p1.x = " + p1.x);

System.out.println("p1.y = " + p1.y);

Pointクラスのオブジェクトを作成して、(その住所を)変数p1に代入します

Pointクラスのオブジェクトを作成して、(その住所を)変数p2に代入します

変数p2の値(Pointクラスのオブジェクトの住所)を変数p3に代入します

変数p1の(住所メモの場所にある)オブジェクトが持つ変数に値を代入します

変数p2の(住所メモの場所にある)オブジェクトが持つ変数に値を代入します

変数 p1 の(住所メモの場所にある)オブジェク

トが持つ変数の値を出力します

変数 p2 の(住所メモの場所にある)オブジェク

トが持つ変数の値を出力します

Page 44: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

44

System.out.println("p2.x = " + p2.x);

System.out.println("p2.y = " + p2.y);

System.out.println("p3.x = " + p3.x);

System.out.println("p3.y = " + p3.y);

}

}

Example4_2.javaではPointクラスのオブジェクトをnew演算子を使って2つ生成し、それぞれp1、

p2という名前の変数に代入しています。また、p3という名前の変数には p2の値を代入しています。ここで

代入される値は、p2が参照するオブジェクトそのものではなく、p2の参照情報(図の【住所メモ】)です。つ

まりp3はp2と同じオブジェクトを参照することになります(図4-2参照)。

実行結果は次のようになり、p3の参照するオブジェクトがp2の参照するオブジェクトと同じであることが

確認できます。

p1.x = 1.2

p1.y = 2.3

p2.x = 9.8

p2.y = -8.7

p3.x = 9.8

p3.y = -8.7

図4-2. Example4_2.javaで記述されているコードのイメージ

■まとめ■

・ intやdoubleなどの基本型でないオブジェクトを表す変数は、オブジェクトへの参照を保持します。

・ 参照は、オブジェクトの場所を表す「住所メモ」のようなものだと考えることができます。

4-4 メソッド

■ クラスには値を保持する変数だけでなく、特定の処理を実行する機能をもたせることができます。この機能

を定義したものをメソッドといいます。

変数 p3 の(住所メモの場所にある)オブジェク

トが持つ変数の値を出力します

Page 45: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

45

4-2節ではインスタンス変数を持つクラスを作成する方法を学習しました。クラスには変数の値を保持する

だけでなく、処理を実行する機能を持たせることができます。この機能を定義したものをメソッドといいます。

メソッドには複数の命令を入れることができます。

最も簡単なメソッドはクラスの定義の中に、次のように「void メソッド名()」と記述し、後に続く{}の中

に命令文を入れます。

class クラス名 {

void メソッド名() {

命令文

}

}

先ほど作成した Pointクラスに、オブジェクトの持つ変数 x, yの値を出力する、printPositionとい

うメソッドを追加するには次のように記述します。

Point.java(2)

class Point {

double x;

double y;

void printPosition() {

System.out.println("現在の座標値は(" + x + ", " + y + ")です");

}

}

上記のように、Pointクラスのメソッドの中では、Pointクラスに定義されている変数(xとy)を使用で

きます。

メソッドで定義された命令を実行するには、オブジェクトの変数にアクセスしたときと同じように、オブジ

ェクト名とメソッド名をドット(.)でつなげて次のように記述します。

オブジェクト名.メソッド名();

オブジェクトのメソッドを実行することを、オブジェクトのメソッドを呼び出すともいいます。

Example4_3.javaは、Pointクラスに新しく定義したprintPositionメソッドを使用する例です。

Example4_3.java

class Example4_3 {

public static void main(String args[]) {

Point p = new Point();

p.x = 1.2;

p.y = 2.3;

p.printPosition();

}

}

Example4_3.javaを実行すると、次の文字列が出力されます。

新しく追加し

たメソッドで

す。変数の x

と y の値を出

力します。

Pointクラスのオブジェクトを作成して、変数pに代入します

変数pのオブジェクトが持つ変数に値を代入します

pのprintPositionメソッドを呼び出します

インスタンス変数xとyを使用できます

メソッドの定義です

Page 46: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

46

現在の座標値は(1.2, 2.3)です

Pointクラスに定義したメソッド内の命令が実行されていることが確認できます。

メモ Example4_3.javaファイルをコンパイルする前に、Point.javaファイル内に変更を反映して、コ

ンパイルしなおしておきましょう。

ところで、Example4_3自体もクラスであることに注意しましょう。Example4_3には mainという名前

のメソッドが定義されています。コマンドプロンプトでjavaコマンドによってプログラムを実行するときに、

まず最初に実行されるのが、このmainメソッドです。

■まとめ■

・ クラスには特定の処理を行うメソッドを定義できます。

・ メソッドを実行するには、オブジェクト名の後ろにドット(.)を記し、続けてメソッド名を記述します。

・ javaコマンドでプログラムを実行すると、クラスに定義されたmainメソッドが最初に実行されます。

4-5 メソッドの引数と戻り値

■ メソッドには処理に用いる値を引数として渡すことができます。また、メソッドで処理を行った結果を戻

り値として呼び出し側で受け取ることもできます。

前節の例では「オブジェクトの持っている変数の値を出力する」という単純な処理を行うメソッドを作成し

ましたが、メソッドには処理に用いる値を引数として渡すことができます。2-8節で学習した「コマンドライ

ン引数」のように、メソッド側で引数を受け取ることで、その引数に応じた処理を行うことができます。また

メソッドで処理を行った結果を戻り値として呼び出し側で受け取ることもできます(図4-3)。

引数と戻り値の仕組みを使うことで、たとえば「引数として数値を1つ受け取り、それを2倍した値を戻り

値として返す」というようなメソッドを作成できるようになります。

図4-3. 引数を受け取り、戻り値を返すメソッドのイメージ

引数と戻り値を持つメソッドは次のように記述します。

戻り値の型 メソッド名(引数列) {

命令文

return 戻り値;

}

引数が無い場合は前節の例のように引数列は空のままにできます。引数がある場合、「引数列」には「引数の

Page 47: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

47

型 変数名」を記述します。複数の引数を指定する場合は「引数の型 変数名」の組をカンマで区切って列挙し

ます。戻り値が無い場合は「戻り値の型」にvoidと記述し、return文を省略できます。

引数で渡された値を変数 xに加えるメソッドを addXという名前で前節の Pointクラスに追加する場合、

次のようなメソッドの定義を追加します。

void addX(double dx) {

x += dx;

}

上記の addXメソッドは double型の値を引数として 1つ受け取ります。また、戻り値が無いため retun

文はありません。

変数xと変数yの値を掛け合わせた値を返すメソッドをgetXYという名前で定義する場合、次のように記

述します。

double getXY () {

return x * y;

}

上記のgetXYメソッドには引数がありません。また、戻り値はdouble型の値です。

これらのメソッドを追加したPointクラスのコードは次のようになります。

Point.java(3)

class Point {

double x;

double y;

void printPosition() {

System.out.println("現在の座標値は(" + x + ", " + y + ")です");

}

void addX(double dx) {

x += dx;

}

double getXY () {

return x * y;

}

}

Example4_4.javaは上記のPointクラスを使用する例です。

Example4_4.java

class Example4_4 {

public static void main(String args[]) {

Point p = new Point();

p.x = 1.5;

新しく追加したメソッドで、xに引数の値を加えます。

引数はdouble型の値で、戻り値はありません。

新しく追加したメソッドで、xとyの値を掛け合わせた値を返します。

引数は無く、戻り値はdouble型です。

インスタンス変数xの値に引数で渡されたdxの値を加算します

変数xと変数yの値を掛けたものを戻り値とします

戻り値が無いのでvoidと記述します。引数はdouble型で名前をdxとしています

戻り値がdouble型で、引数はありません

Pointクラスのオブジェクトを作成して、変数pに代入します

変数pのオブジェクトが持つ変数に値を代入します

Page 48: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

48

p.y = 2.0;

System.out.println("現在のpの座標値を出力します");

p.printPosition();

System.out.println("pのxの値に2.0を加えます");

p.addX(2.0);

System.out.println("現在のpの座標値を出力します");

p.printPosition();

double xy = p.getXY();

System.out.println("pのxとyの値の積は" + xy + "です");

}

}

Example4_4.java を実行すると、次のように出力されます。Point クラスに定義した各メソッドが実行

されていることを確認しましょう。

現在のpの座標値を出力します

現在の座標値は(1.5, 2.0)です

pのxの値に 2.0を加えます

現在のpの座標値を出力します

現在の座標値は(3.5, 2.0)です

pのxとyの値の積は7.0です

■まとめ■

・ メソッドで引数を受け取る場合は、メソッドの宣言で括弧の中に引数の型と名前を列挙します。メソッドを

呼び出す側は、括弧の中に引数の値を指定します。

・ メソッドに戻り値を設ける場合は、メソッドの宣言の先頭に戻り値の型を記し、メソッド内に return 文

を記述します。

練習問題

1. 長方形を表す Rectangle クラスを次のようなコードで作成しました。コンパイルして

Rectangle.classというファイルが作成されることを確認しましょう。

class Rectangle {

double width; // 幅

double height; // 高さ

}

2. 1.で作成したRectangleクラスを使用するコードを次のように作成しましたが、コンパイルするとエ

ラーが発生しました。問題点を指摘し、修正してください。

Practice4_2.java

class Practice4_2 {

pのprintPositionメソッドを呼び出します

引数に2.0を指定してpのaddXソッドを呼び出します

pのprintPositionメソッドを呼び出します

pのgetXY()メソッドを呼び出し、その戻り値を変数xyに代入します

PointクラスのprintPositionメソッドの出力です

PointクラスのprintPositionメソッドの出力です

Page 49: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

49

public static void main(String args[]) {

Rectangle r; // Rectangleクラスのオブジェクトを格納する変数rを宣言する

r.width = 3.0; // rの持つ変数widthに3.0を代入する

r.height = 1.5; // rの持つ変数heightに1.5を代入する

}

}

3. 1.で作成した Rectangleクラスに、長方形の面積を戻り値とする getArea()メソッドを追加してく

ださい。

4. 2.で修正したコードに、3.で作成したメソッドを使って、長方形の面積を求めるコードを追加してく

ださい。

Page 50: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

50

第 5 章 クラスのはたらき

5-1 コンストラクタ

■ クラスにはコンストラクタという特別なメソッドを定義できます。コンストラクタは、クラスのオブジェ

クト(インスタンス)が作成される時に自動的に実行されるメソッドです。

クラスには変数とメソッドを定義できることを前章で学習しました。これ以外にも、クラスにはコンストラ

クタという特別なメソッドを定義できます。コンストラクタは、クラスのオブジェクト(インスタンス)が作

成される時に自動的に実行されるメソッドで、次のような特徴があります。

・ 戻り値を定義できない

・ 通常のメソッドと同じように引数を指定できる

・ オブジェクトが作成される時に、自動的に実行される

・ クラス名と同じ名前のメソッドにしなければならない

・ 省略できる(無くても構わない)

たとえば、次のコードはSimpleClassというクラスにコンストラクタを定義した例です。

SimpleClass.java

class SimpleClass {

SimpleClass() {

System.out.println(

"SimpleClassのコンストラクタが実行されました");

}

}

Example5_1.javaは上記のSimpleClassのオブジェクトを1つ作成するコードです。

Example5_1.java

class Example5_1 {

public static void main(String args[]) {

SimpleClass s = new SimpleClass();

}

}

Example5_1.javaを実行すると画面に

SimpleClassのコンストラクタが実行されました

という文字列が出力されます。Example5_1 では SimpleClass クラスのオブジェクトを生成しただけで、

何かメソッドを実行したわけではありません。オブジェクトが生成される時に、そのクラスのコンストラクタ

が自動的に実行されたことが確認できます。このことを利用して、コンストラクタにはオブジェクトが生成さ

れるときに行うべき初期化処理を記述できます。

具体的な例として、Circle.javaに示すCircle(円)クラスを見てみましょう。

コンストラクタの定義です。コン

ストラクタはクラス名と同じ名

前で戻り値が無いメソッドです。

SimpleClass クラスのオブジェクトを

生成します

Page 51: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

51

Circle.java

class Circle {

double x; // 中心のx座標値

double y; // 中心のy座標値

double radius; // 半径

}

Circleクラスには、中心の座標(x, y)と、半径(radius)を表す変数が含まれます。4-2節で扱った

Pointクラスと似ています。

この Circle クラスのオブジェクトを 1 つ作成し、そのオブジェクトが持つ変数の値を出力するコードを

Example5_2.javaのように記述してみます。

Example5_2.java

class Example5_2 {

public static void main(String args[]) {

Circle c = new Circle();

System.out.println("c.x = " + c.x);

System.out.println("c.y = " + c.y);

System.out.println("c.radius = " + c.radius);

}

}

Example5_2.javaの実行結果は次のようになります。

c.x = 0.0

c.y = 0.0

c.radius = 0.0

【コラム:変数の初期値】

C言語では変数を宣言した時点の値は不定ですが、Java言語ではintやdoubleなどの基本型の変数は、

初期値がゼロに、boolean型の変数は初期値がfalseになります。

オブジェクトの参照を保持する変数(Example5_2.javaの例ではc)の初期値は、参照先が無いことを表

す「null」になります。

例えば次のコードのcのように、宣言しただけの変数は参照先が無い(参照先がnullである)ため誤りで

す。

Circle c;

c.x = 10;

正しくは、2行の間に次の1行を入れて、新しく生成したオブジェクト(の参照)を代入する必要がありま

す。

c = new Circle();

先ほどの例では、初期値として変数の値が全てゼロでした。ここで、「半径がゼロというのは円として不適切

なため、半径の初期値は1に設定したい」と考えた場合、Circleクラスにコンストラクタを追加し、その中

Circleクラスのオブジ

ェクト c の変数を出力

します

Circle クラスのオブジェクトを生成し

ます

オブジェクトcは中心座標が(0, 0)で半径が0であることがわかります。

Page 52: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

52

radius = 1.0;

と記述することで、半径の初期値を1にすることができます。このように変更したコードは次のようになりま

す。

Circle.java(2)

class Circle {

double x; // 中心のx座標値

double y; // 中心のy座標値

double radius; // 半径

Circle() {

radius = 1.0;

}

}

Circle.javaだけを変更し、Example5_2.javaを実行した結果は次のようになります。

c.x = 0.0

c.y = 0.0

c.radius = 1.0

コンストラクタは 4-5 節で学習したメソッドと同じように引数を受け取ることができます。たとえば

Circleクラスのコンストラクタを、半径の値を引数として受け取るように変更した場合、次のようになりま

す。

Circle.java(3)

class Circle {

double x; // 中心のx座標値

double y; // 中心のy座標値

double radius; // 半径

Circle(double r) {

radius = r;

}

}

コンストラクタに渡す引数の値はnew演算子を使用してオブジェクトを生成する時に指定します。上のよう

に定義されたCircleクラスのオブジェクトを生成するには、次のように引数を指定します。

Circle c = new Circle(5.0);

上の例では、半径の初期値が5.0のCircleクラスのオブジェクトが生成されます。

■まとめ■

・コンストラクタは、クラスのオブジェクト(インスタンス)が作成される時に自動的に実行されます。

Circleクラスにradiusを1に設定するコンストラクタを追加し

ました。

オブジェクトcは最初から半径が1に設定されていることがわかります

double型の引数を1つ持つコンストラクタです。

半径の値(radius)を引数に指定された値に設定します。

Page 53: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

53

・コンストラクタには、戻り値を定義できませんが、引数を指定できます。

・コンストラクタには、オブジェクトの初期化処理を記述できます。

5-2 コンストラクタのオーバーロード

■ クラスには引数の異なるコンストラクタを複数定義できます。このことをオーバーロードといいます。

クラスには引数の異なるコンストラクタを複数定義☆できます。このことを、コンストラクタのオーバーロ

ードといいます。オブジェクトが生成される時に、実際に実行されるコンストラクタは1つだけですが、どの

コンストラクタが実行されるかは引数の型と数によって識別されます。

先ほどのCircleクラスに、引数の無いコンストラクタ、引数が1つあり半径を指定できるコンストラクタ、

さらに引数が3つあり中心座標と半径の両方を指定できるコンストラクタを追加した場合、次のようなコード

になります。

Circle.java(4)

class Circle {

double x; // 中心のx座標値

double y; // 中心のy座標値

double radius; // 半径

Circle() {

radius = 1.0;

}

Circle(double r) {

radius = r;

}

Circle(double tx, double ty, double r) {

x = tx;

y = ty;

radius = r;

}

}

Example5_3.java は、上のように 3 種類のコンストラクタがある Circle クラスのオブジェクトを、3

通りの方法で生成する例です。

Example5_3.java

class Example5_3 {

public static void main(String args[]) {

Circle c1 = new Circle();

Circle c2 = new Circle(3.0);

引数の無いコンストラクタです。

中心座標を(0, 0)、半径を1に設定します。

引数が1つあるコンストラクタです。

中心座標を(0, 0)、半径を引数で渡された値に設定します。

引数が3つあるコンストラクタです。

中心のx座標を1番目の引数、y座標を2番目

の引数、半径を3番目の引数で渡された値に設

定します。

引数の無いコンストラクタを使用します

引数が1つのコンストラクタを使用します

Page 54: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

54

Circle c3 = new Circle(2.0, 5.0, 4.0);

System.out.println("c1.x = " + c1.x);

System.out.println("c1.y = " + c1.y);

System.out.println("c1.radius = " + c1.radius);

System.out.println("c2.x = " + c2.x);

System.out.println("c2.y = " + c2.y);

System.out.println("c2.radius = " + c2.radius);

System.out.println("c3.x = " + c3.x);

System.out.println("c3.y = " + c3.y);

System.out.println("c3.radius = " + c3.radius);

}

}

Example5_3を実行すると画面に次のような結果が出力されます。オブジェクトを生成するときの引数の数

によって、実行されるコンストラクタが異なることがわかります。

c1.x = 0.0

c1.y = 0.0

c1.radius = 1.0

c2.x = 0.0

c2.y = 0.0

c2.radius = 3.0

c3.x = 2.0

c3.y = 5.0

c3.radius = 4.0

■まとめ■

・クラスには引数の異なるコンストラクタを複数定義できます。このことをオーバーロードといいます。

・オブジェクトが生成される時に、実行されるコンストラクタは1つだけです。

・どのコンストラクタが実行されるかは引数の型と数によって識別されます。

5-3 thisキーワード

■ thisキーワードは、そのキーワードが使われているオブジェクト自身を指します。

オブジェクト(インスタンス)の変数にアクセスするには.(ドット)を使用して

インスタンス名.変数名

と記述しました(Example5_1の例では c1.x など)。

この「インスタンス名」にthisというキーワードを使用すると、自分自身の変数にアクセスします。

つまり、this というキーワードは自分自身を指すわけです。今まで引数で用いる変数名は、クラスの属性

である変数名と異なるものにして、次のようにコードを記述しました。

Circle(double tx, double ty, double r) {

x = tx;

引数が3つのコンストラクタを使用します

引数の無いコンストラクタを使って生成されたオブジェクトc1の情報です。

中心座標が(0, 0)、半径が1に設定されています。

引数で半径を指定するコンストラクタを使って生成されたオブジェクトc2の情報です。

中心座標が(0, 0)、半径が3に設定されています。

引数で中心座標と半径を指定するコンストラクタを使って生成されたオブジェクト c3 の

情報です。中心座標が(2, 5)、半径が4に設定されています。

3つの double型の引数を、それぞれ

tx,ty,rという名前で受け取ります 自身のxにtxの値を代入します

Page 55: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

55

y = ty;

radius = r;

}

this キーワードを使うと、次のように引数の変数名とクラスの属性の変数名が同じでも問題ありません。

このようにすると、引数の名前をインスタンス変数の名前と同じにできるので、コードを読んで理解しやすい

という利点があります。

Circle(double x, double y, double radius) {

this.x = x;

this.y = y;

this.radius = radius;

}

自身の変数へのアクセスだけでなく

this(引数)

と記述することで、自身のコンストラクタを実行できます。ただし、この記述が使えるのはコンストラクタの

先頭行だけです。

このことを利用すると、複数のコンストラクタで重複する内容を1つにまとめて、次のようにコードをすっ

きりさせることができます。次のコードは Circle.java(2)の一部を変更したものですが、処理の内容はま

ったく同じです。

Circle.java(5)

class Circle {

double x; // 中心のx座標値

double y; // 中心のy座標値

double radius; // 半径

Circle() {

this(0.0, 0.0, 1.0);

}

Circle(double radius) {

this(0.0, 0.0, radius);

}

Circle(double x, double y, double radius) {

this.x = x;

this.y = y;

this.radius = radius;

}

}

■まとめ■

・ thisキーワードは、そのキーワードが使われているオブジェクト自身を指します。

自身のyにtyの値を代入します

自身のradiusにrの値を代入します

3 つの double 型の引数を、それぞれ

x,y,radiusという名前で受け取ります 自身のxに引数で渡されたxの値を代入します

自身のyに引数で渡されたyの値を代入します

自身のradiusに引数で渡されたradiusの値を代入します

引数が3つのコンストラクタを実行します

引数が3つのコンストラクタを実行します

引数が3つあるコンストラクタです。

中心のx座標を1番目の引数、y座標を2番目

の引数、半径を3番目の引数で渡された値に設

定します。

Page 56: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

56

・ 引数で受け取る変数名と、インスタンス変数名が同じでもthisキーワードを使うことでインスタンス変数

を識別できます。

5-4 メソッドのオーバーロード

■ クラスには引数の異なる同じ名前のメソッドを複数定義できます。このことをメソッドのオーバーロード

といいます。

前節では、コンストラクタをオーバーロードしました。これと同じことをメソッドでも行えます。つまり同

じ名前で引数が異なるメソッドを複数定義できます。

たとえば2つの引数で指定した場所に中心座標を設定するメソッドと、3つの引数で指定した場所と大きさ

に中心座標と半径を設定するメソッドをCircleクラスに追加する場合、どちらも同じ名前にすることができ

ます。次のコードは、両方ともsetという名前のメソッドにした場合の例です。同じ名前のメソッドでも、呼

び出すときに渡される引数の数で、どちらが実行されるか区別されます。

void set(double x, double y) {

this.x = x;

this.y = y;

}

void set(double x, double y, double radius) {

this.x = x;

this.y = y;

this.radius = radius;

}

■まとめ■

・クラスには引数の異なる同じ名前のメソッドを複数定義できます。このことをオーバーロードといいます。

・どのメソッドが実行されるかは引数の型と数によって識別されます。

5-5 静的変数

■ クラスには、同じクラスのオブジェクト全体で共有する変数を定義できます。このような変数を静的変数

といいます

クラスには変数を定義できることを4章で学習しました。変数にはオブジェクトごとに異なる値を格納でき、

これをインスタンス変数といいました。Javaでは同じクラスのオブジェクト全体で 1つの変数を共有する仕

組みがあります。このような変数を静的変数といいます。静的変数は、そのクラスのすべてのオブジェクトか

ら共有されます。

クラスの宣言の中で、次のようにstaticキーワードをつけて変数を宣言すると、この変数は静的変数とな

ります。

static 型 変数名;

また、この静的変数にアクセスするには、

クラス名.変数名

と記述します。つまり、静的変数は特定のオブジェクトに属するのではなく、クラスそのものに属していると

3 つの double 型の引数を、それぞれ

x,y,radiusという名前で受け取ります 自身のxに引数で渡されたxの値を代入します

自身のyに引数で渡されたyの値を代入します

自身のradiusに引数で渡されたradiusの値を代入します

2つのdouble型の引数を、それぞれx,y

という名前で受け取ります 自身のxに引数で渡されたxの値を代入します

自身のyに引数で渡されたyの値を代入します

Page 57: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

57

見なすことができます。

メモ 静的変数には、通常の変数のように「オブジェクト名.変数名」としてもアクセスできます。

次の Ball.javaは静的変数を使用したクラスの例です。内部で countという名前の静的変数を定義して

います。コンストラクタが実行されると、この値が1増えます。

Ball.java

class Ball {

static int count; // Ballクラスのオブジェクト数を格納

int size; // ボールのサイズを表す変数

Ball(int size) {

System.out.println("サイズ" + size + "のBallオブジェクトを生成します");

this.size = size;

count++;

}

}

Example5_4は Ballクラスのオブジェクトを生成するごとに、Ballクラスの静的変数 Ball.countの

値を出力する例です。

Example5_4.java

class Example5_4 {

public static void main(String args[]) {

System.out.println("Ball.count = " + Ball.count);

Ball b1 = new Ball(3);

System.out.println("Ball.count = " + Ball.count);

Ball b2 = new Ball(5);

System.out.println("Ball.count = " + Ball.count);

Ball b3 = new Ball(1);

System.out.println("Ball.count = " + Ball.count);

}

}

Example5_4を実行すると次のように出力されます。

Ball.count = 0

サイズ3のBallオブジェクトを生成します

Ball.count = 1

サイズ5のBallオブジェクトを生成します

Ball.count = 2

サイズ1のBallオブジェクトを生成します

Ball.count = 3

countという名前の静的変数を宣言しています

自身のsizeに引数で渡された値を代入します

静的変数countの値を1増やします

Ball

クラス

のコン

ストラ

クタで

size=3のBallオブジェクトを生成します。

size=5のBallオブジェクトを生成します。

size=1のBallオブジェクトを生成します。

Page 58: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

58

Ballクラスのイメージは図5-1のようになります。

Ballクラスにはcountとsizeという2つの変数がありますが、sizeは各オブジェクト毎に異なる値を

格納し、count は Ball クラスに属する値で全てのオブジェクトから共有されます。Ball クラスに属する

sizeという変数は存在しません(Ball.sizeと記述するとコンパイル時にエラーが発生します)。

図5-1. 静的変数とインスタンス変数の違い

■まとめ■

・静的変数の定義にはstaticキーワードを用います。

・静的変数は、オブジェクト全体で共有されます。

・静的変数には、クラス名の後ろにドット(.)を記し、その後に変数名を記述してアクセスできます。

5-6 静的メソッド

■ クラスには、オブジェクトを生成しなくても使用できるメソッドを定義できます。このようなメソッドを

静的メソッドといいます

変数に静的変数が存在するように、メソッドにも静的メソッドというものがあります。静的変数と同じよう

に、静的メソッドは各オブジェクトではなくクラスに属するメソッドであり、静的変数と同じようにクラス名

に.(ドット)をつけて次のような記述でメソッドを呼び出すことができます。

クラス名.メソッド名(引数)

静的メソッドを宣言するには、今まで学習したメソッドの宣言の前にstaticキーワードをつけて、次のよ

うに記述します。

static 戻り値 メソッド名(引数) {

処理

}

次のSimpleCalcクラスは、int型の引数aとbを受け取り、aからbまでの整数を足した和を返す静的

Page 59: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

59

メソッドgetSumを持っています。

SimpleCalc.java

class SimpleCalc {

static int getSum(int a, int b) {

int sum = 0;

for(int i = a; i <= b; i++) {

sum += i;

}

return sum;

}

}

SimpleCalcクラスで定義されているgetSumメソッドを使った例は次のようになります。

Example5_5.java

class Example5_5 {

public static void main(String args[]) {

int sum = SimpleCalc.getSum(10, 20);

System.out.println("10から20までの整数の和は" + sum + "です");

}

}

実行結果は次のように出力されます。

10から20までの整数の和は165です

静的メソッドは、SimpleCalcの単純な計算の例のように、インスタンスに依存しない特定の処理を行うメ

ソッドを定義するのに便利です。

■まとめ■

・静的メソッドの定義にはstaticキーワードを用います。

・静的メソッドは、オブジェクトを生成しなくても、クラス名の後ろにドット(.)を記し、続けてメソッド名

を記述して使用できます。

5-7 Mathクラス

■ Javaには数学的なメソッドばかりを集めたMathクラスというものが予め準備されています。Mathクラ

スには便利な静的メソッドが多数あります。

Mathクラスには、表5-1のような静的メソッドがあります。これらは知っておくと便利なメソッドです。

また、MathクラスにはE(自然対数の底:2.71828..)とpI(円周率:3.14192..)という静的定数が定

義されています。

表5-1 Mathクラスの静的メソッド

静的メソッドの宣言では、static キーワードを戻り

値の型の前に記述します。

合計値を格納する変数を宣言し、0を代入しています

ループでiの値をaからbまで1つずつ増やします

変数sumにiの値を加算します

メソッドの最後で変数sumの値を返します

静的メソッドは「クラス名.メソッド名」で呼び出せます

Page 60: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

60

メソッド 説明

static double abs(double d) dの絶対値を返す

static int abs(int i) iの絶対値を返す

static double sin(double radians) radiansの正弦(サイン)を返す

static double cos(double radians) radiansの余弦(コサイン)を返す

static double tan(double radians) radiansの正接(タンジェント)を返す

static double sqrt(double d) dの平方根を返す

static double pow(double x, double y) xのy乗を返す

static double log(double d) dの自然対数を返す

static double max(double d, double e) dとeの大きいほうの値を返す

static int max(int i, int j) iとjの大きいほうの値を返す

static double min(double d, double e) dとeの小さいほうの値を返す

static int min(int i, int j) iとjの小さいほうの値を返す

static double random() 0.0以上で1.0より小さい乱数を返す

Example5_6.javaは、Mathクラスの使用例です。

Example5_6.java

class Example5_6 {

public static void main(String args[]) {

System.out.println("-5の絶対値は" + Math.abs(-5));

System.out.println("3.0の平方根は" + Math.sqrt(3.0));

System.out.println("円周率は" + Math.PI);

System.out.println("sin(60°)は" + Math.sin(60.0 * Math.PI / 180.0));

}

}

実行結果は次のように出力されます。

-5の絶対値は5

3.0の平方根は1.7320508075688772

円周率は3.141592653589793

sin(60°)は0.8660254037844386

■まとめ■

・ Javaに予め準備されているMathクラスには数学的な演算を行うのに便利な静的メソッドが多数あります。

・ Mathクラスのより詳しい説明はAPI仕様書(7-4節)を参照しましょう。

練習問題

1. コンストラクタとはどのようなものか説明してください。

2. オーバーロードとはどのようなことか説明してください。

3. x,y,zの3次元座標値を持つ点を表すクラスPoint3Dを次のように定義しました。それぞれの座標値

を引数で指定できるコンストラクタを追加してください。なお、コンストラクタ内では thisキーワー

ドを使うようにしてください。

Page 61: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

61

class Point3D {

double x; // x 座標値

double y; // y 座標値

double z; // z 座標値

}

4. インスタンス変数と静的変数の違いを説明してください。

5. ★ページのSimpleCalcクラスに、引数で渡された値の2乗を返すgetSquaredValueという名前の

静的メソッドを追加してください。ただし引数も戻り値もdouble型にしてください。

Page 62: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

62

第 6 章 継承

6-1 継承とは

■ 新しく作成するクラスが既存のクラスと共通点が多い場合、既存のクラスの機能を再利用できれば効率的に

新しいクラスを作成できます。Java では、このように既存のクラスの機能を拡張して新しいクラスを作成す

るための仕組みが準備されています。このことを「継承」といいます。

継承はオブジェクト指向を理解するうえで大切な概念です。継承とは、あるクラスの機能を別のクラスが引

き継ぐことをいいます。新しいクラスを定義する場合に、既にあるクラスの機能を引き継いで、必要な機能だ

けを新しく追加することで、効率的に新しいクラスを開発できます。

既にXという名前のクラスが存在し、そのXが持つ機能に新しい機能を追加してYというクラスを作成した

場合、「クラスYはクラスXを継承する」といいます。この場合、YをXのサブクラスと呼び、XをYのスー

パークラスと呼びます。「YはXから派生したクラス」と呼ぶこともあります。

1つのクラスは複数のサブクラスを持つことができますが、1つのクラスは1つのスーパークラスしか持つ

ことができません。したがって、クラスは継承に基づく図6-1のような階層関係が成り立ちます。

Object クラス

クラスA クラスB クラスC

クラスD クラスE クラスF

図6-1. 継承によるクラスの階層関係

図6-1の例では、クラスDとクラスEはクラスAのサブクラスで、クラスAはクラスDとクラスEのスー

パークラスです。継承は何段階にも行え、クラス Dにサブクラスを作ることもできます。Javaでは、階層の

最も上位のクラスは「Object」クラスで、すべてのクラスはこの Objectクラスを直接、または間接的に継

承します。今まで作成したクラスも、暗黙的にこのObjectクラスを継承していました。

図6-1のようにクラスDがクラスAを継承する場合、extendsキーワードを用いて次のようにコードを記

述します。

class A {

クラスA の定義

}

class D extends A {

クラスD の定義

}

クラスAはObjectクラスを継承しますが、extends Object という記述は省略してもよいことになって

います。

今まで学習した方法でクラスAを定義します

(クラスA は暗黙的にObjectクラスを継承しています)

クラス名の後にextends Aと記述することで、クラスDはク

ラスAを継承することを宣言します

Page 63: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

63

メモ 今までは、1つのjavaファイルに1つのクラスの定義しか含まれませんでしたが、1つのファイルに

複数のクラスの定義を記述することもできます。コードをコンパイルすると、定義されているクラスの数だけ

classファイルが生成されます。上の例では、A.classとD.classが生成されます。

■まとめ■

・ あるクラスの属性や機能を別のクラスが引き継ぐことを継承といいます。

・ クラスYがクラスXを継承する場合、YをXのサブクラスと呼び、XをYのスーパークラスといいます。

・ 継承関係をコードで記述するにはextendsキーワードを使用します。

6-2 変数、メソッド、コンストラクタの継承

■ サブクラスはスーパークラスの変数、メソッド、コンストラクタを引き継ぎます。

◆サブクラスとスーパークラスの関係

継承関係において、サブクラスはスーパークラスにプラスアルファの機能を追加したものと考えることがで

きます。Javaでは、extendsキーワードを用いるだけで、サブクラスがスーパークラスの機能(変数、メソ

ッド、コンストラクタ)を自動的に引き継ぐ(継承する)ので、コードを記述する際には差分の「プラスアル

ファ」の部分だけを記述すればよいことになっています。この仕組みにより、既にあるクラスを拡張して新し

いクラスを容易に作成できます。

メモ extends とは英語で「拡張する」という意味です。Java での「継承」とは、既存のクラスを拡張し

て新しいクラスを作成することをいいます。

◆変数の継承

Example6_1.javaの例では、Person(人)クラスと、それを継承するStudent(学生)クラスを定義して

います。学生はもちろん人間ですから、人が持っている属性(例えば「名前」)は学生も持っています。しかし、

学生が持っている属性(例えば「学生番号」)は、あらゆる人が持っているわけではありません。このような関

係にある場合、「学生」を表すクラスは「人」を表すクラスを拡張したものだと考えることができます。したが

って、これを Javaのプログラムで扱う場合には、人を表す Personクラスは今まで学習した方法で定義し、

学生を表すStudentクラスはPersonクラスを継承するものとして定義できます。

Example6_1.java

Page 64: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

64

class Person {

String name;

}

class Student extends Person {

int studentNumber;

}

class Example6_1 {

public static void main(String args[]) {

Student taro = new Student();

taro.studentNumber = 101;

taro.name = "太郎";

}

}

Example6_1の mainメソッドでは Studentクラスのオブジェクトを生成しています。Studentクラス

の定義にnameという名前の変数は含まれませんが、StudentクラスはPersonクラスを継承しているため、

Personクラスで定義されたnameという変数を引き継いでいます。この関係は図6-2のようになります。

図6-2. Personクラスを継承するStudentクラスの概要(1)

◆メソッドの継承

変数と同じように、サブクラスはスーパークラスのメソッドも継承します。したがって、スーパークラスで

定義されているメソッドは、それを継承するサブクラスのオブジェクトに対しても呼び出すことができます。

Example6_2.javaでは、先ほどのPersonクラスと、それを継承するStudentクラスにメソッドの定義

を追加したものです。Example6_2のmainメソッドではStudentクラスのオブジェクトを生成し、それぞ

れのメソッドを呼び出しています。

今まで学習した方法でPersonクラスを定義しています。

nameというString型の変数を持ちます。

Personクラスを継承するStudentクラスを定義しています。

studentNumberというint型の変数が追加されます。

Studentクラスのオブジェクトを生成します

変数nameはPersonクラスに定義されていますが、Studentク

ラスはPersonクラスを継承しているのでStudentクラスのオブ

ジェクトでも使用できます

変数studentNumberはStuudentクラスに定義されています

Page 65: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

65

Example6_2.java

class Person {

String name;

void printName() {

System.out.println("名前は" + name);

}

}

class Student extends Person {

int studentNumber;

void printStudentNumber() {

System.out.println("学生番号は" + studentNumber);

}

}

class Example6_2 {

public static void main(String args[]) {

Student taro = new Student();

taro.studentNumber = 1021;

taro.name = "太郎";

taro.printStudentNumber();

taro.printName();

}

}

Studentクラスの定義にprintNameという名前のメソッドは含まれませんが、StudentクラスはPerson

クラスを継承しているため、Personクラスで定義されたprintNameというメソッドを引き継いでいます。

この関係を図に表すと図6-3のようになります。

今まで学習した方法で Person クラスを定義

しています。nameという名前のString型の

変数と、名前を出力する printName という

メソッドを持ちます。

Person クラスを継承する

Student クラスを定義していま

す。studentNumberというint

型の変数と、学生番号を出力する

printStudentNumber という

メソッドが追加されています。

Studentクラスのオブジェクトを生成します

変数nameはPersonクラスに定義されていますが、Student

クラスはPersonクラスの変数を継承します

変数studentNumberはStuudentクラスに定義されています

printStudentNumberメソッドはStuudentクラスに定義されています

printName メソッドは Person クラスに定義されていますが、Student クラスは Person

クラスを継承しているのでStudentクラスのオブジェクトでも使用できます

Page 66: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

66

図6-3. Personクラスを継承するStudentクラスの概要(2)

Example6_2 を実行した結果は次のようになります。Student クラスのオブジェクトに対して、Person

クラスで定義されているprintNameメソッドを呼び出せていることがわかります。

名前は太郎

学生番号は1021

◆コンストラクタの継承

変数やメソッドと同じように、サブクラスはスーパークラスのコンストラクタも継承します。しかし、コン

ストラクタの継承は変数とメソッドの継承より少し複雑です。

サブクラスのオブジェクトが生成されるとき、まずスーパークラスのコンストラクタが実行され、それに続

いてサブクラスのコンストラクタが実行されます。

Example6_3.javaは、スーバークラスとサブクラスの両方にコンストラクタが定義されている場合に、サ

ブクラスのオブジェクトを生成すると、どのようにコンストラクタが実行されるかを確認するための例です。

Example6_3.java

class Person {

String name;

Person() {

System.out.println("Personクラスのコンストラクタが実行されました");

name = "名無し";

}

}

class Student extends Person {

int studentNumber;

Student() {

System.out.println("Studentクラスのコンストラクタが実行されました");

studentNumber = 1000;

}

Person クラス

のコンストラク

タを定義してい

ます。nameを"

名無し"に初期

化します。

Person クラス

を 継 承 す る

Student クラ

スのコンストラ

クタを定義して

い ま す 。

studentNumb

erを1000に初

期化します。

Page 67: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

67

}

class Example6_3 {

public static void main(String args[]) {

Student s = new Student();

System.out.println("s.studentNumber = " + s.studentNumber);

System.out.println("s.name = " + s.name);

}

}

実行結果は次のようになります。

Personクラスのコンストラクタが実行されました

Studentクラスのコンストラクタが実行されました

s.studentNumber = 1000

s.name = 名無し

Student クラスのオブジェクトを生成すると、Student クラスのコンストラクタに先立って、まずスーパ

ークラスであるPersonクラスのコンストラクタが実行されていることが確認できます。

■まとめ■

・ サブクラスはスーパークラスの変数、メソッド、コンストラクタを引き継ぎます。

・ サブクラスのオブジェクトを生成すると、スーパークラスのコンストラクタが先に実行され、続いてサブ

クラスのコンストラクタが実行されます。

6-3 メソッドのオーバーライド

■ サブクラスでスーパークラスと同じ名前の変数やメソッドを定義することができます。このことをオーバ

ーライドといいます。

継承関係にあるサブクラスはスーパークラスの変数とメソッド、コンストラクタを引き継ぐことを見てきまし

た。また、サブクラスで新しい変数やメソッドを定義して、スーパークラスの機能を拡張することができまし

た。しかし、サブクラスでスーパークラスと同じ名前の変数やメソッドを定義した場合はどうなるでしょうか。

この場合、サブクラスでの定義が優先されるようになります。このことをオーバーライドといいます。

Example6_4.javaは、Personクラスと Studentクラスの両方に printInfoという同じ名前のメソ

ッドを定義した例です。

Example6_4.java

class Person {

String name;

void printInfo() {

System.out.println("Personです");

System.out.println("名前は" + name + "です");

}

}

Studentクラスのオブジェクトを生成します

Studentクラスのオブジェクトの変数を出力します。

Personクラスを定義しています。

nameという名前のString型の変

数と、名前を出力する printInfo

というメソッドを持ちます。

Page 68: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

68

class Student extends Person {

int studentNumber;

void printInfo() {

System.out.println("Studentです");

System.out.println("学生番号は"

+ studentNumber + "です");

}

}

class Example6_4 {

public static void main(String args[]) {

Person ichiro = new Person();

ichiro.name = "一郎";

ichiro.printInfo();

System.out.println("---");

Student taro = new Student();

taro.studentNumber = 1021;

taro.name = "太郎";

taro.printInfo();

}

}

Example6_4.javaの実行結果は次のようになります。

Personです

名前は一郎です

---

Studentです

学生番号は1021です

サブクラスがスーパークラスに定義されたメソッドと同じ名前のメソッドを持つ場合、サブクラスのメソッ

ドが優先され、スーパークラスのメソッドは実行されません(隠蔽されます)。この関係を図に表すと図 6-4

のようになります。

Personクラスを継承するStudentク

ラスを定義しています。Person クラ

スで定義されているメソッドと同じ名

前の printInfo メソッドが定義され

ています。

Person クラスのオブジェクトを生成し、変数

nameに値を設定しています。

PersonクラスのprintInfoメソッドが実行されます

Student クラスのオブジェクトを生成し、変数

に値を設定しています。

Studentクラスで定義されたprintInfoメソッドが実行されます

PersonクラスのprintInfoメソッドでの処理です

StudentクラスのprintInfoメソッドでの処理です

Page 69: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

69

図6-4. Personクラスを継承するStudentクラスの概要(3)

隠蔽されたスーパークラスのメソッドを、サブクラスから実行するには、super キーワードを使って次のよ

うに記述します。

super.メソッド名(引数)

例えば、Example6_4.javaのStudentクラスのprintInfoメソッドの中に

super.printInfo();

と記述することで、PersonクラスのprintInfoメソッドを呼び出すことができます。

class Student extends Person {

int studentNumber;

void printInfo() {

super.printInfo();

System.out.println("Studentです");

System.out.println("学生番号は" + studentNumber + "です");

}

}

この変更だけ加えてExample6_4.javaを実行した結果は次のようになります。

Personです

名前は一郎です

---

Personです

名前は太郎です

Studentです

学生番号は1021です

新しく追加した行です。スーパークラス(Person

クラス)に定義された printInfo メソッドを呼び

出します

PersonクラスのprintInfoメソッドでの処理です

StudentクラスのprintInfoメソッドでの処理です

Student クラスの printInfo メソッド中の super.printInfo メソッドでは

Personクラスで定義されたprintInfoメソッドが実行されます

Page 70: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

70

■まとめ■

・サブクラスでスーパークラスと同じ名前の変数やメソッドを定義することをオーバーライドといいます。

・ オーバーライドした変数やメソッドは、サブクラスのものが優先され、スーパークラスのものは隠蔽されま

す。

・ 隠蔽されたスーパークラスの変数やメソッドにアクセスするには、superキーワードを使用します。

6-4 クラスの継承と参照

■ スーパークラスの型の変数に、サブクラスのオブジェクトの参照を代入できます。

2 つのクラスが継承関係にあるとき、スーパークラスの型の変数に、サブクラスのオブジェクトの参照を代

入することができます☆。このことはクラスの継承を学習する上で大切なものですが、文章だけでは理解が難

しいので、次のような簡単なコードを例に説明します。

class Person {

// Personクラスの定義

}

class Student extends Person {

// Studentクラスの定義

}

class Car {

// Carクラスの定義

}

上記のコードでは、Personクラス、Studentクラス、Carクラスの3つのクラスを定義しています。Person

クラスとCarクラスは独立したクラスですが、StudentクラスはPersonクラスを継承しています(Student

クラスはPersonクラスのサブクラスです)。

このように定義されたクラスは、それぞれ次のようなコードでオブジェクトを作成し変数に代入することが

できます。

Person p = new Person();

Student s = new Student();

Car c = new Car();

ところで、4-3節で述べたように、オブジェクトはそのまま変数に格納されるのではなく、オブジェクトの

存在する場所を表した「住所メモ」が変数に格納されます。これを「参照」といいました。Personクラスの

オブジェクトの参照を格納する変数を「Person型」の変数ともいいます。

上記の3行のコードで、それぞれのオブジェクトを生成して参照を変数に代入している様子は図6-5のよう

になります。

StudentクラスはPersonクラスを継承します

Page 71: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

71

図6-5. 変数に格納されるオブジェクトの参照

例に示した Personクラスと Carクラスは、それぞれ独立したクラスなので、次の 2つの命令はどちらも

誤りになります。

Person p = new Car();

Car c = new Person();

ところが、StudentクラスはPersonクラスのサブクラスなので、次のようにPerson型の変数にStudent

クラスのオブジェクトの参照を代入することができます。

Person p = new Student();

この様子を図に表したものが図6-6になります。このように、スーパークラスの型の変数にサブクラスの型の

参照を代入できるということは、以降で学習する「抽象クラス」や「インターフェイス」を扱うときに役立ち

ます。

図6-6. 継承と変数に格納できる参照の関係

■まとめ■

・ 2つのクラスが継承関係にあるとき、スーパークラスの型の変数に、サブクラスのオブジェクトの参照を代

入することができます。

Person型の変数pにCarクラスのオブジェクトの参照は代入できません

Car型の変数cにPersonクラスのオブジェクトの参照は代入できません

Page 72: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

72

6-5 修飾子

■ クラスや変数、メソッドを定義する際に、修飾子を用いることで、アクセスを制御したり属性を定めるこ

とができます。

◆修飾子とは

クラスや変数、メソッドを定義する際に、そのアクセスを制御したり属性を定めるために修飾子を用いるこ

とができます。アクセスの制御は個人で小規模なプログラムを開発する際には、特に意識しなくても問題あり

ませんが、大規模なプログラムを複数人で開発する場合には重要になります。たとえば変数へのアクセスを他

のクラスから禁止すると、その変数の値は外部から参照したり変更できないようになります。

修飾子はクラスやメソッドの宣言の前につけるキーワードで、省略することもできます(今までのコードで

は特に理由がない限り修飾子は省略していました)。修飾子には様々な種類が存在しますが、ここでは主なもの

数種類について紹介します。

◆クラスの修飾子

次のような修飾子をクラスの宣言の前につけることで、クラスの性質を定義できます。

abstract インスタンスを生成できないクラス。このようなクラスを抽象クラスとも言う。

final サブクラスを生成できないクラス。

public 他のどのクラスからも参照できるクラス。

使用例

public class Person {

クラスの定義

}

※ 修飾子を指定しない場合は、abstractでもfinalでもないクラスとして解釈され、同一パッケージから

のみ参照できるクラスとなります(☆パッケージについては7-5説で説明します)。

◆変数の修飾子

次のような修飾子を変数の宣言の前につけることで、変数の性質を定義できます。

final 後から値を変更できない。定数として使用できる。

private 同じクラス内のコードからしかアクセスできない変数。

protected サブクラスまたは同じパッケージ内のコードからしかアクセスできない変数。

public 他のどのクラスからもアクセスできる変数。

static 静的変数。

使用例

private int counter;

※ 修飾子を指定しない場合は、同一パッケージからのみアクセスできる変数となります。

◆コンストラクタの修飾子

次のような修飾子をコンストラクタの宣言の前につけることで、コンストラクタの性質を定義できます。

private 同じクラス内のコードからしかアクセスできないコンストラクタ。

protected サブクラスまたは同じパッケージ内のコードからしかアクセスできないコンストラクタ。

public 他のどのクラスからもアクセスできるコンストラクタ。

Page 73: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

73

使用例

public Person() {

コンストラクタの定義

}

※ 修飾子を指定しない場合は、同一パッケージからのみアクセスできるコンストラクタとなります。

◆メソッドの修飾子

次のような修飾子をメソッドの宣言の前につけることで、メソッドの性質を定義できます。

final オーバーライドできないメソッド。

private 同じクラス内のコードからしかアクセスできないメソッド。

protected サブクラスまたは同じパッケージ内のコードからしかアクセスできないメソッド。

public 他のどのクラスからもアクセスできるメソッド。

static 静的メソッド。

使用例

static void printInfo() {

メソッドの定義

}

※ 修飾子を指定しない場合は、同一パッケージからのみアクセスできるメソッドとなります。

■まとめ■

・アクセスを制御するキーワードには、public,protected,privateがあり、順にアクセスできる範囲が

狭くなります。

・staticキーワードは静的変数と静的メソッドを定義するために使用します。

・finalキーワードは変更できない変数、サブクラスを作成できないクラス、オーバーライドできないメソッ

ドの定義に使用します。

6-6 抽象クラス

■ abstract 修飾子をクラスの宣言に追加することで、インスタンス(オブジェクト)を作成できない抽

象クラスを定義できます。

前節では、クラスに修飾子をつけることで、そのクラスの性質を定義できることを説明しました。例えばク

ラスの宣言にabstractという修飾子をつけた場合、インスタンスを作成できないクラスとなります。このよ

うなクラスを抽象クラスとよびます。この抽象クラスは次章のインターフェイスの理解にも役立つ概念ですの

で、ここでは使用例を紹介します。

抽象クラスは先頭にabstractキーワードをつけて宣言します。たとえばShape(形)という名前のクラス

を抽象クラスとして宣言するには次のように記述します。

abstract class Shape {

abstract void printArea();

}

このような抽象クラスはオブジェクト(=インスタンス)が作成できないという特徴があります。

つまり、今までのように

Shape s = new Sahpe();

クラスの宣言の先頭にabstractキーワードをつけます

Page 74: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

74

というように新しいオブジェクトを生成するためのコードを記述するとコンパイル時にエラーになります。こ

のように、抽象クラスからはオブジェクトを作成できないため、それを継承するサブクラスを定義し、そのサ

ブクラスのオブジェクトを作成することになります。

たとえば、Shape クラスを継承する Circle(円)クラスと Square(正方形)クラスを定義した場合、これ

らのサブクラスのオブジェクトは生成できます。

ところで、上の Shape クラスには printArea()メソッドが宣言されていますが、メソッドの先頭にも

abstractキーワードがついていて、中身が定義されていません。このようなメソッドを抽象メソッドとよび

ます。抽象クラスを継承するサブクラスは、この抽象メソッドを必ずオーバーライドしなくてはなりません(オ

ーバーライドについて 6-3節参照)。抽象メソッドは「このようなメソッドがある」という事実だけを記し、

実際にメソッドで行われる処理の定義はサブクラスで行う必要があります。

この抽象クラス Shapeと、それを継承するクラスとして、Circleクラスと Squareクラスを定義して使

用した例が Example6_5.javaです。このコードで記述されているクラスとオブジェクト間の関係は図 6-7

のようになります。

抽象クラスは、それを継承するクラスがただ1つの場合はあまり存在する意味がありませんが、サブクラス

が複数ある場合、抽象クラスを作成するメリットがあります。それは、6-4節で説明したように、スーパーク

ラスの変数はサブクラスのオブジェクトを参照できるためです。

図6-7. 抽象クラスと継承

Example6_5.java

abstract class Shape {

public void printMessage() {

System.out.println("ShapeクラスのprintMessageメソッド");

}

abstract void printArea();

}

class Circle extends Shape {

private double radius;

抽象メソッドの宣言です。メソッドの処理は定義しません。

通常のクラスのメソッドと同じように宣言しています

Circle(円)クラスの宣言です。Shapeクラスを継承しています

インスタンス変数としてradius(半径)の値を持ちます

Shape(形)クラスの宣言です。abstractキーワードがつけられています

Page 75: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

75

public Circle(double radius) {

this.radius = radius;

}

public void printArea() {

System.out.println("半径" + radius + "の円:面積は"

+ radius * radius * Math.PI + "です");

}

}

class Square extends Shape {

private double width;

public Square(double width) {

this.width = width;

}

public void printArea() {

System.out.println("1辺" + width + "の正方形:面積は"

+ width * width + "です");

}

}

class Example6_5 {

public static void main(String args[]) {

Shape shapes[] = new Shape[3];

shapes[0] = new Circle(5.0);

shapes[1] = new Square(3.0);

shapes[2] = new Circle(7.0);

for(int i = 0; i < shapes.length; i++) {

shapes[i].printMessage();

shapes[i].printArea();

}

}

}

Example6_5を実行した結果は次のようになります。

ShapeクラスのprintMessageメソッド

半径5.0の円:面積は78.53981633974483です

ShapeクラスのprintMessageメソッド

1辺3.0の正方形:面積は9.0です

ShapeクラスのprintMessageメソッド

半径7.0の円:面積は153.93804002589985です

■まとめ■

・abstractキーワードをつけて宣言したクラスは抽象クラスになります。

Circleクラスのコンストラクタです

抽象クラスShapeを継承する

クラスは、Shapeクラスで宣

言された抽象メソッド

printArea を必ず持ってい

る必要があります

インスタンス変数としてwidth(幅)の値を持ちます

Squareクラスのコンストラクタです

抽象クラスShapeを継承する

クラスは、Shapeクラスで宣

言された抽象メソッド

printArea を必ず持ってい

る必要があります

Square(正方形)クラスの宣言です。Shape クラスを継承していま

Shape型の配列を準備しています

配列の0番目にCircleオブジェクトを代入しています

配列の1番目にSquareオブジェクトを代入しています

配列の2番目にCircleオブジェクトを代入しています

配列の数だけループ処理を行います

各要素のprintMessageメソッドを呼び出します

各要素のprintAreaメソッドを呼び出します。要素

が参照するオブジェクトがCircleクラスかSquare

クラスかによって実行される処理が異なります

Shapeクラスに定義されたprintMessageメソッドが実行されました

Shapeクラスに定義されたprintMessageメソッドが実行されました

Shapeクラスに定義されたprintMessageメソッドが実行されました

Circleクラスに定義されたprintAreaメソッドが実行されました

Squareクラスに定義されたprintAreaメソッドが実行されました

Circleクラスに定義されたprintAreaメソッドが実行されました

Page 76: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

76

・抽象クラスはインスタンス(オブジェクト)を作成できません。

・抽象クラスを継承するクラスは、抽象メソッドをオーバーライドする必要があります。

練習問題

1. 次の文章のうちクラスの継承について誤っているものを選択してください。

(1) クラスAがクラスBを継承するとき、クラスAをクラスBのサブクラスと呼ぶ

(2) あるクラスを継承するサブクラスが複数存在することもある

(3) あるクラスのスーパークラスが複数存在することもある

(4) サブクラスは、スーパークラスに定義されている変数やメソッドを引き継ぐ

(5) オブジェクトが生成されるとき、サブクラスのコンストラクタが実行されてからスーパークラスの

コンストラクタが実行される

2. メソッドのオーバーライドとはどのようなものか説明してください。

3. 次のようにクラスA,B,Cが定義されています。

class A { }

class B extends A { }

class C { }

次の変数の宣言と代入で誤りがあるのはどれですか。

(1) A a = new A(); (2) A a = new B(); (3) A a = new C(); (4) B b = new A(); (5) B b = new B(); (6) B b = new C();

4. 抽象クラスとはどのようなものか説明してください。

Page 77: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

77

第 7 章 インターフェイスとパッケージ

7-1 インターフェイスとは

■ インターフェイスとはクラスに含まれるべき定数とメソッドを定義したもので、クラスはインターフェイ

スを実装することができます。

インターフェイスとはクラスの役割を示すためのもので、クラスに含まれるべき定数とメソッドを定義した

ものです。インターフェイスの宣言は次の構文を用いて記述します。

interface インターフェイス名 {

型1 変数名1 = 値1;

戻り値の型1 メソッド名1(引数1);

}

メモ プログラミングの学習を始めたばかりの時には、インターフェイスを自分で作成する必要はあまりあり

ません。しかし、マウスで操作できるアプレットを作る場合(11章)などに、Javaに予め準備されている特

定のインターフェイスを使用する必要がでてきます。まずはじめは、インターフェイスの作り方よりもインタ

ーフェイスの仕組みと使い方を理解するようにしましょう。

インターフェイス内部に変数やメソッドを複数定義できます。変数は特に修飾子をつけない限り、public

static final、メソッドには abstract という修飾子をつけていることと同じになります。つまり、変数

は値の変化しない定数として扱われ、インターフェイスは抽象メソッドとして扱われます。

そのため、インターフェイスの定義の中では変数の具体的な値を指定し、メソッドの中身は定義しません。

具体的な「定数」と抽象的な「このようなメソッドがあるということ」を宣言するものがインターフェイスだ

ということができます。実際のメソッドの中身の定義は、このインターフェイスを実装するクラスの中で行い

ます。「インターフェイスを実装する」とは、スーパークラスに定義された抽象メソッドをサブクラスで定義し

たこと(6-6節)と似ています。

インターフェイスを実装するには、クラスの宣言で

class クラス名 implements インターフェイス名

と記述し、インターフェイスで定義されている全てのメソッドをクラスの中で定義します。

これは 6-6節で学習した抽象クラスの継承と似ていますが、インターフェイスは図 7-1のように、クラス

の継承関係とは関係の無いところで実装できるという点が異なります。さらに1つのクラスが複数の異なるイ

ンターフェイスを同時に実装することもできます。図 7_1のように、クラス Cがインターフェイス Yとイン

ターフェイスZを実装する場合、次のようにインターフェイス名をカンマ(,)で区切って並べます。

class C implements Y, Z

変数の定義です。具体的な値を指定します。

メソッドの定義です。具体的な中身は定義しません。

Page 78: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

78

図7-1. クラスの継承とインターフェイスの実装の関係

■まとめ■

・ インターフェイスとはクラスに含まれるべき定数とメソッドを定義したものです。

・ インターフェイスを実装するには、クラスの宣言で「implements インターフェイス名」を記述します。

・ インターフェイスを実装するクラスは、インターフェイスに含まれるメソッドを定義する必要があります。

7-2 インターフェイスの使い方

■ インターフェイス型の変数で、そのインターフェイスを実装したクラスのオブジェクトを参照できます。

6-4節ではスーパークラスの型の変数でサブクラスのオブジェクトを参照できることを説明しました。これ

と同じように、インターフェイス型の変数で、そのインターフェイスを実装したクラスのオブジェクトを参照

できます。これにより、異なるクラスのオブジェクトも、インターフェイスという共通の型のオブジェクトと

して参照できるというメリットがあります。

このことをもう少し具体的に見ていきましょう。

たとえば、次のようにSimpleInterfaceという名前のインターフェイスがあったとします。

interface SimpleInterface {

// インターフェイスの定義

}

このインターフェイスをSimpleClassAとSimpleClassBという名前の2つのクラスがそれぞれ実装す

る場合、次のようにコードを記述します。

class SimpleClassA implements SimpleInterface {

// SimpleClassAの定義

}

class SimpleClassB implements SimpleInterface {

// SimpleClassBの定義

}

今まで学習した内容では、SimpleClassAとSimpleClassBのオブジェクトはそれぞれ次のように変数に

(参照を)代入できました。

SimpleClassA sa = new SimpleClassA();

SimpleClassB sb = new SimpleClassB();

ところで、SimpleClassAもSimpleClassBもSimpleInterfaceというインターフェイスを実装して

いるので、次のようにSimpleInterface型の変数に代入することもできます。

SimpleInterface si1 = new SimpleClassA();

SimpleInterface si2 = new SimpleClassA();

Example7_1.javaは、より具体的にインターフェイスを利用した例です。このコードで記述されている内

Page 79: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

79

容を表したものが図7-2になります。抽象クラスのShapeと、それを継承するCircleクラスとSquareク

ラス、さらにPolygonal(多角形)インターフェイスが存在します。クラスの種類が3つしかないので、イ

ンターフェイスを定義する利点はあまりないのですが、これ以外にも数多くのクラスが存在するような場合、

同じインターフェイスを実装している様々なクラスを、全て共通のインターフェイス型のオブジェクトとして

管理できるという利点があります。

上で述べたSimpleInterfaceとSimpleClassAの関係と同じように、Polygonalインターフェイスを

Squareクラスが実装しているので、Squareクラスのオブジェクトへの参照をPolygonalというインター

フェイス型の変数に格納できます。

図7-2. インターフェイスの実装

Example7_1.java

abstract class Shape {

public void printMessage() {

System.out.println("ShapeクラスのprintMessageメソッド");

}

abstract void printArea();

}

interface Polygonal {

int getNumberOfCorners();

}

class Circle extends Shape {

private double radius;

public Circle(double radius) {

this.radius = radius;

}

public void printArea() {

System.out.println("半径" + radius + "の円:面積は"

Example6_5.java

と同じ Shape クラ

スの定義です。

Polygonal(多角形)という名前のインターフェイスの定義です。この定義

では、 Polygonal インターフェイスを実装するクラスには

getNumberOfCornersという名前のメソッドが含まれることになります。

Example6_5.java と

同じ Circle クラスの

定義です。Shape クラ

スを継承しています。

Page 80: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

80

+ radius * radius * Math.PI + "です");

}

}

class Square extends Shape implements Polygonal {

private double width;

public Square(double width) {

this.width = width;

}

public void printArea() {

System.out.println("1辺" + width + "の正方形:面積は"

+ width * width + "です");

}

public int getNumberOfCorners() {

return 4;

}

}

class Example7_1 {

public static void main(String args[]) {

Polygonal p = new Square(1.0);

System.out.println(

"頂点の数は" +

p.getNumberOfCorners());

}

}

Example7_1.javaを実行した結果は次のようになります。

頂点の数は4

■まとめ■

・インターフェイス型の変数で、そのインターフェイスを実装したクラスのオブジェクトを参照できます。

7-3 instanceof演算子

■ instanceof演算子を用いて、オブジェクトのクラスやオブジェクトに実装されているインターフェイス

を確認できます。

オブジェクトのクラスや、オブジェクトに実装されているインターフェイスを確認するにはinstanceof演

算子を使用します。instanceof演算子は次の構文で使用します。

オブジェクト参照変数 instanceof クラス名またはインターフェイス名

ここで、参照されているオブジェクトがinstanceofキーワードの後ろのクラス(またはクラスのサブクラ

ス)である場合、またはインターフェイスを実装している場合、この式は真(true)と評価されます。そうで

Example6_5.java と

同じSquareクラスの定

義です。ただし、今回は

Polygonal インターフ

ェイスを実装していま

す 。 そ の た め 、

getNumberOfCorner

s という名前のメソッド

が追加されています。

SquareクラスのインスタンスをPolygonal型

の変数 s に代入しています。Square クラスは

Polygonal インターフェイスを実装しているの

でこのようなことができます

Polygonal 型 の オ ブ ジ ェ ク ト に は

getNumberOfCorners メソッドを呼び出せま

す。

Page 81: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

81

ない場合は偽(false)です。

Example7_2.java は instanceof 演算子を使用して、配列に格納されているオブジェクトの型を識別し

て、その結果に応じて行う処理を切り替える例です。なお、Example7_1.javaのShape, Circle, Square

クラスとPolygonalインターフェイスの定義をそのまま使用した場合の例です。行っている処理は異なりま

すが、実行結果はExample7_1.javaと同じになります。

Example7_2.java

class Example7_2 {

public static void main(String args[]) {

Shape shapes[] = new Shape[3];

shapes[0] = new Circle(5.0);

shapes[1] = new Square(3.0);

shapes[2] = new Circle(7.0);

for(int i = 0; i < shapes.length; i++) {

shapes[i].printMessage();

shapes[i].printArea();

if(shapes[i] instanceof Polygonal) {

Polygonal p = (Polygonal)shapes[i];

System.out.println(

"頂点の数は" +

p.getNumberOfCorners());

}

}

}

}

■まとめ■

・オブジェクトのクラスやオブジェクトに実装されているインターフェイスを確認するにはinstanceof演

算子を使用します。

7-4 API仕様書の見方

■ API仕様書を見ることで、Javaに予め準備されているクラスやインターフェイスの詳細を知ることがで

きます。

今までは、Java言語のクラスやインターフェイスの仕組みと、それらを新しく定義して使用する方法を学習

してきました。ところで、Java には予め準備された便利なクラスやインターフェイスがたくさんあります。

これらはライブラリとよばれ、必要に応じて自由に使うことができます。

JDKをインストールしたときに、自動的に準備されるクラスやインターフェイスはJavaのAPI仕様書で確

認できます(API= Application Program Interface)。API仕様書には、クラスやインターフェイスの

働きや使い方、含まれるメソッドや変数、コンストラクタの一覧とそれぞれの説明など、プログラミングを進

める上で有益な情報がまとめられています。本書のサンプルコードや他人の作ったコードなどを見ていて、使

配列の数だけループ処理を行います

Example6_5 と同じように、Shape 型の配列を準備

し、各要素にCircleクラスとSquareクラスのオブ

ジェクトを代入します。

配列の要素が Polygonal インターフェイ

スを実装しているか調べます

Polygonal インターフェイスを実装

しているオブジェクトは Polygonal

型の変数から参照可能です。

Example7_1のように、Polygonal

インターフェイスに定義されているメ

ソッドを実行しています

Page 82: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

82

い方のわからないクラスやメソッドが出てきた場合は、まず最初にAPI仕様書で調べるようにしましょう。

執筆時現在、日本語版の最新のAPI仕様書は次のURLで見ることができます。

http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html

上記のURLのページをインターネットブラウザで開くと図7-3のような画面になります。

図7-3. API仕様書をインターネットエクスプローラで表示した様子

API仕様書のWebページは図7-3のように、3つの領域に分割されています。はじめにページを開いた時点

では、Java で予め準備されている全てのクラス名の一覧が左下の領域に表示されます。この中から調べたい

クラスの名前を探し、クラス名をクリックすると右側の大きな領域にそのクラスの詳しい説明が表示されます。

予め目的のクラスが属しているパッケージがわかっている場合は、左上の領域でパッケージ名を選択すると、

左下に表示されるクラスを絞り込むことができます(パッケージについては次節で学習します)。

クラスの数は膨大ですが、インターネットエクスプローラでは[Ctrl]+F ボタンで特定のキーワードを検索

できるので、この機能を使うと便利です。左下の領域を一度マウスでクリックしてから[Ctrl]+Fボタンを押

すと、図7-4のような検索ダイアログが表示されるので、検索する文字列に「Applet」と入力すると、Applet

クラスを見つけることができます。

図7-4. クラス名の検索

目的のクラス名をクリックして表示される詳細情報には、次のようなものが含まれます。

Page 83: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

83

・ クラスの継承関係

・ クラスに実装されているインターフェイス

・ クラスのサブクラス

・ クラスの説明文

・ フィールド(インスタンス変数、静的変数)

・ コンストラクタ

・メソッド

それぞれの説明の中で、他のクラスのメソッドやインターフェイスなどのキーワードにはリンクが付けられ

ているので、それらを辿ることでさらに詳しく調べることができます。

Java は言語としての仕組みが優れているだけでなく、予め準備された豊富なクラス群があることで、自由

度の高いプログラムを効率的に作成できるようになっています。たくさんあるクラスをうまく使いこなせるよ

うに、API仕様書をまめに調べることを習慣づけるようにしましょう。

■まとめ■

・Javaには予め準備された便利なクラスやインターフェイスがたくさんあります。

・API仕様書を見ることで、これらの詳細を知ることができます。

7-5 パッケージの利用

■クラスやインターフェイスは用途や目的に応じて複数のパッケージに分類されています。

Javaには便利なクラスやインターフェイスが予めたくさん準備されています。これらは用途や目的に応じて

複数のパッケージに分類されています。パッケージとはクラスやインターフェイスを集めたものです。

パッケージの中には、さらにパッケージを含めることができ、階層構造をもたせることができます。階層構造

はパッケージ名とパッケージ名の間に(.)をつけて表現します。

geometryという名前のパッケージの中にutilという名前のパッケージがある場合には

geometry.util

のように記述します。

Javaに準備されている主なパッケージには表7-1のようなものがあります。

表7-1 Javaの主なパッケージ

パッケージ名 説明

java.applet アプレットを作成するためのクラス群

java.awt グラフィカルなインターフェイスを行うためのクラス群。AWT(Abstract

Window Toolkit)が含まれます。

java.awt.event AWTコンポーネントからのイベントを処理するためのクラス群

java.io 入出力を扱うクラス群

java.lang Javaの基本的な機能を提供するクラス群

java.net ネットワーク機能を提供するクラス群

java.util 便利な機能を提供するクラス群

今まではパッケージというものを意識せずにコードを記述してきましたが、パッケージに含まれるクラスを使

Page 84: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

84

用する場合、コード中ではパッケージ名の後ろにピリオド(.)を付け、その後ろにクラス名を続けて記述しま

す。

パッケージ名.クラス名

例えばjava.awtパッケージにはButtonという名前のクラスがあります。このButtonクラスをコードの

中で使用するには次のように記述します。

java.awt.Button

このようなパッケージ名を含めたクラス名の記述を完全修飾クラス名といいます。

このオブジェクトを作成する場合、次のように記します。

java.awt.Button b = new java.awt.Button();

このような記述は入力する文字が多くなるので、何度も登場する場合に入力の手間がかかって不便です。

そこで import キーワードを使ってコードの先頭に次のように記すことで、コードの中でパッケージ名の記

述を省略できます。

import パッケージ名.クラス名;

java.awtパッケージの中のButtonクラスを使用する場合、次のように記述できます。

Example7_3.java

import java.awt.Button;

class Example7_3 {

public static void main(String args[]) {

Button b = new Button();

}

}

使用するクラスが複数ある場合、上記の記述をクラスの数だけ繰り返します。java.awt パッケージの中の

ButtonクラスとCheckBoxクラスを使用する場合、次のように記述します。

import java.awt.Button;

import java.awt.CheckBox;

しかし、使用するクラスが多くなってくると、このような記述も大変になってきます。そこで、同じパッケー

ジに含まれるクラスはアスタリスク(*)記号を使って、次のように簡単に記述することができます。

import パッケージ名.*;

上記の例では

import java.awt.*;

と記述することもできます。

ただし、java.awtパッケージと、その中にあるjava.awt.eventパッケージは異なるパッケージなので、

上記の記述でjava.awt.eventパッケージ内のクラスを使用することはできません。両方のパッケージのク

ラスを使いたい場合は次のように記述します。

import java.awt.*;

import java.awt.event.*;

コードの先頭のimport文でjava.awtパッケージの

中のButtonクラスを使用することを宣言します。

パッケージ名 クラス名

java.awt.Button のパッケージ名(java.awt)部

分を省略できます

Page 85: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

85

■まとめ■

・パッケージに含まれるクラスを使用するには、パッケージ名の後ろにドット(.)を記し、その後にクラス名

を記述します。

・コードの中で使用するパッケージをimport文で宣言しておくと、パッケージ名の記述を省略できます。

7-6 パッケージの作成

■ パッケージは自分で作ることもできます。パッケージを使うことで効率的にクラスの管理を行えます。

前節ではJavaには予め様々なパッケージが存在することと、それを使用する方法を述べました。このような

パッケージは自分で作ることもできます。パッケージを使うことで、クラスの数が多い規模の大きいプログラ

ムを開発するときに、効率的にクラスの管理を行えます。

1つのソースファイルに含まれるクラス(またはインターフェイス)を特定のパッケージに含ませるには、次

のようにソースファイルの先頭に記述します。

package パッケージ名;

パッケージ名には好きな名前を指定できます。

たとえば、コードの中で定義するクラスを myclasses という名前のパッケージに含ませるには、コードの

先頭に次のように記述します。

package myclasses;

次のコードはmyclassesというパッケージの中にPackageTestという名前のクラスを定義した例です。

myclasses¥PackageTest.java

package myclasses;

public class PackageTest {

public void printMessage() {

System.out.println("myclassesパッケージのPackageTestクラスです");

}

}

パッケージを使って複数のクラスやインターフェイスを管理する場合、ファイルの配置に注意する必要があり

ます。Java ではパッケージの階層構造がファイルを保存するディレクトリの階層構造を使って管理されてい

るためです。myclassesというパッケージを作成するためには、パッケージと同じ「myclasses」という名

前をつけたフォルダを作業中のフォルダの中に作成して、そこにコードを保存します。

つまり、今まで「c:¥java」というフォルダで作業していた場合は「c:¥java¥myclasses」というフォル

ダを作成し、その中に上記のPackageTest.javaファイルを保存します。

コンパイルは作業ディレクトリから次のように入力して行います。

c:¥java>javac myclasses¥PackageTest.java

コンパイルした結果、myclassesディレクトリにPackageTest.classファイルが作成されます。このよ

うにして、パッケージの中にクラスを定義することができます。このクラスは前節で学習した方法で、他のク

ラスから使用できるようになります。

Page 86: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

86

もし同じ名前のクラスが作成された場合でも、パッケージが違えば問題ありません。クラス名の記述に、パッ

ケージ名も含めて記述する完全修飾クラス名を使えば区別できるためです。

前述の例と同じPackageTestという名前のクラスを今度はmyclasses2という名前のパッケージの中に、

次のようにして作成したとします。

myclasses2¥PackageTest.java

package myclasses2;

public class PackageTest {

pubic void printMessage() {

System.out.println("myclasses2パッケージのPackageTestクラスです");

}

}

このような異なるパッケージに含まれる同じ名前のクラスをExample7_4.javaのようにして使用できます。

Example7_4.java

class Example7_4 {

public static void main(String args[]) {

myclasses.PackageTest p1 = new myclasses.PackageTest();

p1.printMessage();

myclasses2.PackageTest p2 = new myclasses2.PackageTest();

p2.printMessage();

}

}

Example7_4を実行した結果は次のようになります。

myclassesパッケージのPackageTestクラスです

myclasses2パッケージのPackageTestクラスです

■まとめ■

・コードの中で定義するクラスを特定のパッケージに含ませるには、コードの先頭で「package パッケージ

名;」の宣言を行います。

・Java ではパッケージの階層構造をディレクトリ構造を使って管理するので、パッケージを扱う際にはコー

ドの保存場所に注意する必要があります。

練習問題

1. インターフェイスとはどのようなものか説明してください。

2. 次の文章で誤っているものを選びなさい

(1) インターフェイスの定義の中ではメソッドが行う処理の内容は定義しない。

同じ名前のクラス

もパッケージ名を

記す完全修飾クラ

ス名で記述すれば

区別できます。

Page 87: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

87

(2) 1つのクラスが実装できるインターフェイスは1つまでである。

(3) インターフェイスを実装するクラスは、インターフェイスに含まれるメソッドを定義してもし

なくてもよい。

3.

interface I { }

class A { }

class B extends A { }

class C implements I { }

上記のように定義された各クラスについて、次のようにオブジェクトを生成しました。

A a = new A();

B b = new B();

C c = new C();

この場合、instanceof演算子を用いた次の式の評価値はtrueとfalseのどちらになるでしょう。

(1) a instanceof A

(2) a instanceof B

(3) b instanceof A

(4) c instanceof A

(5) c instanceof I

4. API仕様書でjava.lang.Mathクラスには、どのようなメソッドがあるか調べましょう。

5. コードの先頭に次のように記述しました。

import java.awt.*;

この場合、このコードの中で完全修飾クラス名を使わなくてもよいのは次のうちどれでしょう。

(1) java.awt.Graphics (2) java.awt.event.ActionEvent (3) java.io.BufferedReader (4) java.lang.System

Page 88: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

88

第 8 章 例外処理

8-1 例外の発生と受け取り

■ プログラムはエラーが発生すること無くコンパイルできたからと言って、いつも問題なく動作するとは限

りません。実行するときになって問題が起きた場合、例外が発生します。

数学では「2÷0」のような、ゼロによる割り算は定義されていません。プログラムの中に、このようなゼロ

で割り算を行う命令や、配列のインデックスの範囲を超えて要素を参照するような命令が含まれると、実行時

に正しく動作しません。これらの問題は、コードをコンパイルする時には知ることができず、プログラムを実

行するときに初めてわかる問題です。

たとえばExample8_1.javaは、ゼロでの割り算が含まれているコードの例です。コード自体に文法上の誤

りは無いため、エラーが発生することなくコンパイルすることができます。

Example8_1.java

class Example8_1 {

public static void main(String args[]) {

int a = 1;

int b = 0;

int c = a / b;

System.out.println("cの値は" + c);

System.out.println("処理を正常に終了します");

}

}

ゼロで割り算をすると結果が求まらないため、このプログラムを実行すると正しく処理が完了せずに次のよ

うなメッセージが出力されます。

Exception in thread "main" java.lang.ArithmeticException: / by zero

at Example8_1.main(Example8_1.java:5)

メッセージは英語ですが「Example8_1.javaのコードの5行目でゼロの除算が行われた」という内容です。

このような問題が発生した場合、Javaではインタプリタが例外を発生させ、残りの処理を中断します。コー

ドの下から3行目にある「処理を正常に終了します」という文字が出力されていないので、問題の発生した箇

所で中断してしまい、最後まで処理が行われなかったことがわかります。

しかし重要な処理を行うプログラムの場合、例外が発生した時点で処理が中断してしまっては困ることがあり

ます。そのため、Javaには例外が発生した場合でも正常に処理を続けるための仕組みが準備されています。

例外が発生した場合に対処するには、次のようなtry-catch構文を使用します。

try {

例外が発生する可能性のある処理

}

catch(例外の型1 変数名1) {

例外が発生した時の処理1

1を0で割っています

Page 89: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

89

}

catch(例外の型2 変数名2) {

例外が発生した時の処理2

}

finally {

最後に行う処理

}

try-chatch構文では、tryブロックの中に例外が発生する可能性のある処理を記述します。例外が発生し

た場合は、catchブロックの中に記述した処理が実行されます。例外が発生してもしなくても、finallyブ

ロックに記述した処理が最後に実行されます。catchブロックは発生する可能性のある例外の数に応じていく

つでも続けられます。また、finallyブロックは省略することができます。

Javaでは発生した「例外」の内容が、それに対応する例外オブジェクトによって表現されます。このオブジ

ェクトの型に応じて、例外が発生した場合の処理を切り替えることができます。具体的には catch ブロック

の引数で指定された型が、例外オブジェクトの型と一致する場合、そのオブジェクトが変数に渡された上で、

catchブロックの中の処理が実行されます。

Example8_1.javaのコードに例外処理の仕組みを追加するとExample8_2.javaのようになります。

Example8_2.java

class Example8_2 {

public static void main(String args[]) {

int a = 1;

int b = 0;

try {

int c = a / b;

System.out.println("cの値は" + c);

}

catch (ArithmeticException e) {

System.out.println("算術計算で例外が発生しました");

}

System.out.println("処理を正常に終了します");

}

}

Example8_2を実行すると、ゼロで除算しているので例外が発生しますが、catch文で例外が受け止められ

るので、最後まで処理が正常に進みます。実行結果は次の出力になります。

算術計算で例外が発生しました

処理を正常に終了します

■まとめ■

・プログラム実行時に問題が起こると、例外が発生します。

・例外に対処するには、try-catch構文を使用します。

例外が発生する可能性があるので、try

ブロックで囲んでいます。

例外が発生した場合の処理です。

ゼ ロ で 除 算 を し た 場 合 に 起 き る

ArithmeticExcption型の例外を受け取ります

Page 90: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

90

8-2 ユーザーが入力する値への対処

■ユーザーの操作やユーザーが入力した値に基づいて処理を行う場合、ユーザーの入力が常に正しいとは限ら

ないため、様々な例外の発生に対処する必要があります。

一般的なプログラムでは、ユーザーの操作やユーザーが入力した値に基づいて処理を行うことが多いですが、

ユーザーの入力が常に正しいとは限らないので、さまざまな要因で例外が発生する可能性があります。

Example8_3.javaは「ユーザーがコマンドライン引数で指定した2つの値で割り算を行う」という単純な

ものですが、この場合でも次の3通りの場合に例外が発生する可能性があります。

・ ユーザーが1つしか値を指定しなかった、または1つも値を指定しなかった場合

・ ユーザーが入力した文字列が数値として正しく解釈できなかった場合

・ 割る値にゼロが指定された場合

Example8_3.javaでは、それぞれの例外に対応できるようにtry-catch構文を使用しています。

Example8_3.java

class Example8_3 {

public static void main(String args[]) {

try {

int a = Integer.parseInt(args[0]);

int b = Integer.parseInt(args[1]);

int c = a / b;

System.out.println("cの値は" + c);

}

catch (ArithmeticException e) {

System.out.println("算術計算で例外が発生しました");

}

catch (ArrayIndexOutOfBoundsException e) {

System.out.println("配列のインデックスが範囲を超えています");

}

catch (NumberFormatException e) {

System.out.println("文字列の形式が数値として正しくありません");

}

System.out.println("処理を正常に終了します");

}

}

chatchブロックで受け取る例外オブジェクトはThrowableクラスのサブクラスです。

図8-1のように、Example8_3.javaで扱っている例外はいずれもThrowableクラスのサブクラスになっ

ています。図8-1は、3つの例外の位置を知るために必要な最低限のものだけを示していますが、Throwable

クラスには非常にたくさんのサブクラスが定義されています。それぞれ、例外の内容に応じて使い分けられま

す。

例外が発生する可能性があるので、tryブロックで囲みます。

引数の1番目の文字列を整数に変換します

引数の2番目の文字列を整数に変換します

2つの値で割り算を行います

それぞれの例

外を受け取る

た め の

catch 文を

並べて記述し

ます。

Page 91: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

91

図8-1.例外クラスの階層

図8-1を見るとThrowableクラスの下にはErrorクラスとExceptionクラスの2つがあります。Error

クラスは処理を継続すべきでない重大なエラーが発生したときに使用するものなので、一般には Exception

クラスを継承するクラスのみをコードでは扱うことになります。

オブジェクトの継承で学習したように、スーパークラスはサブクラスの変数を参照することができるので

(6-4節)、Example8_3.javaはExample8_4.javaのようにcatchで受け止めるクラスをException

型とすれば、3種類の例外を1つのcatchブロックで受け止めることができます。

また、System.out.printlnメソッドの引数に Exception型のオブジェクトを渡すことも可能です。こ

の場合、例外オブジェクトの型(クラス名)などの例外に関する内容が出力されます。

Example8_4.java

class Example8_4 {

public static void main(String args[]) {

try {

int a = Integer.parseInt(args[0]);

int b = Integer.parseInt(args[1]);

int c = a / b;

System.out.println("cの値は" + c);

}

catch (Exception e) {

System.out.println("例外が発生しました");

System.out.println(e);

}

}

}

Example8_4.javaを、実際に様々な引数を与えて実行すると次のようになります。

C:¥java>java Example8_4 100

例外が発生しました

java.lang.ArrayIndexOutOfBoundsException: 1

Exceptionクラスのサブクラスの例外をまとめて受け取ります

例外の内容を出力します

例外が発生する可能性があるので、try

ブロックで囲んでいます。

引数に値を1つしか指定していません

例外オブジェクトの型がわかります

Page 92: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

92

C:¥java>java Example8_4 100 abc

例外が発生しました

java.lang.NumberFormatException: For input string: "abc"

C:¥java>java Example8_4 100 0

例外が発生しました

java.lang.ArithmeticException: / by zero

C:¥java>java Example8_4 100 5

cの値は20

■まとめ■

・コマンド引数でユーザーが値を指定する場合には、様々な例外が発生する可能性があります。

・Exception クラスは全ての例外のスーパークラスであるため、catch ブロックで受け取るオブジェクト

の型にExceptionを指定することで、各種の例外をまとめて受け取ることができます。

8-3 catchブロックの検索

■ 例外が発生した場所にcatchブロックが無い場合、メソッドの呼び出しを遡ってcatchブロックが検索

されます。

前節ではtry-catch構文で例外処理が行えることを記しました。それではcatchブロック☆が無いところ

で例外が発生した場合はどうなるでしょうか。この場合、メソッドの呼び出しを遡って catch ブロックが検

索されます。main メソッドまで遡っても最後まで chatch ブロックが見つからなかった場合は、

Example8_1.javaの例のように途中で処理が中断され、メッセージが表示されます☆。

Example8_5.javaの例では、ExceptionTestクラスのdoSomethingメソッドの中で、配列のインデッ

クスが範囲を超えて使用されているため例外が発生します。しかし、doSomething メソッド内部には

try-catch構文がありません。したがって、このメソッドを呼び出したExample8_5クラスのmainメソッ

ドまで遡ってcatchブロックの検索が行われます。

Example8_5.java

class ExceptionTest {

void doSomething() {

int array[] = new int[3];

array[10] = 1;

System.out.println("doSomethingメソッドが正常に終了しました");

}

}

class Example8_5 {

public static void main(String args[]) {

ExceptionTest et = new ExceptionTest();

2番目の引数に英字文字列"abc"を指定しました

2番目の引数にゼロを指定しました

正しく2つの数字を引数に渡しました

1番目の値を2番目の値で割った値が正しく出力されました

ExceptionTestクラスのdoSomethingメソッドの宣言です

int型で要素数が3の配列を生成しています

配列のインデックスの指定(10)が範囲(2)を超えています

例外オブジェクトの型がわかります

例外オブジェクトの型がわかります

Page 93: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

93

try {

et.doSomething();

}

catch (Exception e) {

System.out.println("Example8_5クラスのmainメソッドで例外を受け取りました");

System.out.println(e);

}

}

}

実行結果は次のようになります。ExceptionTest クラスのメソッドで発生した例外が、メソッドを呼び出

した側であるExample8_5クラスのmainメソッドで受け取られています。

Example8_5クラスのmainメソッドで例外を受け取りました

java.lang.ArrayIndexOutOfBoundsException: 10

■まとめ■

・例外が発生した場所に catchブロックが無い場合、メソッドの呼び出しを遡って catchブロックが検索

されます。

・catch ブロックが見つかると、そこへ処理が移ります。見つからなかった場合は例外が発生した場所で処

理が中断します。

8-4 例外の作成と送出

■ 例外オブジェクトを自分で作成して送出することができます。

前節で学習した例外は、プログラム実行中に発生した問題に対して、システム(インタプリタ)が自動的に生

成したものでした。Java では、例外オブジェクトを受け取るだけでなく、自分で生成して送出(throw)す

ることができます。

例外を表すExceptionクラスには次のようなコンストラクタがあり、引数のmessageには例外の内容を表

す文字列を指定できます。

Exception(String message)

次のようなコードで新しい例外オブジェクトを生成できます。

Exception e = new Exception("○○という例外が発生しました");

このようにして生成した例外オブジェクトは、次のthrow構文を使って送出できます。

throw 例外オブジェクト;

例外オブジェクトはjava.lang.Throwable型でなくてはなりません。ExceptionクラスはThrowable

クラスのサブクラスなので、Exceptionクラスのオブジェクトは問題なく使用できます。

このthrow構文で例外オブジェクトを送出すると、その後に続く処理はスキップされ、この例外オブジェク

トが受け止められるcatchブロックを検索して、そのcatchブロックに定義された処理が実行されます。

Example8_6.javaは引数で渡された値の平方根を出力するコードですが、負の値が渡された場合は例外オ

ブジェクトを作成して送出します。

ExceptionTest型のオブジェクトのdoSomethingメソッドを呼

び出しています

例外を受け取ります

例外の内容を出力します

Page 94: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

94

Example8_6.java

class Example8_6 {

public static void main(String args[]) {

try {

double d = Double.parseDouble(args[0]);

if(d < 0) {

Exception e = new Exception("引数に負の値が渡されました");

throw e;

}

System.out.println("平方根は" + Math.sqrt(d) + "です");

}

catch (Exception e) {

System.out.println(e);

}

}

}

Example8_6.javaに正の値を引数にして実行すると、正しく平方根の値が出力されますが、負の値を渡し

た場合、例外が送出されて catch ブロックの中の処理が実行されます。この際、平方根の出力処理はスキッ

プされます。引数に"5"と"-5"を渡した結果は次のようになります。

>java Example8_6 5

平方根は2.23606797749979です

>java Example8_6 -5

java.lang.Exception: 引数に負の値が渡されました

■まとめ■

・Exceptionクラスのオブジェクトを作成し、throw文を使って送出できます。

・Exceptionクラスのオブジェクトにはコンストラクタで独自のメッセージを設定できます。

8-5 メソッドの外への例外の送出

■ 自分で作成した例外オブジェクトをメソッドの外へ送出することができます。

例外オブジェクトを送出する場合、同じメソッドの中でcatchせずに、メソッドの外へ送出することができ

ます。この場合、メソッドの呼び出し元で例外を受け取る必要があります☆。

例外を送出する可能性のあるメソッドを作成する場合、メソッドの宣言で次のように throws キーワードを

用いて宣言を行います。

戻り値 メソッド名(引数) throws 例外の型 {

例外を送出するメソッドの定義

}

PositiveX.javaは、正の値だけを変数xに保持するクラスです。変数の値を設定するためのメソッドとし

例外が発生する可能性があるので、tryブロックで囲んでいます

コマンドライン引数の値を変数dに代入します

dの値が負であった場合に例外オブジェクトを生成して送出します

dの平方根を出力します

例外を受け取ります

例外の内容を出力します

Page 95: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

95

てsetXを定義していますが、引数に負の値が渡されたときには例外オブジェクトを生成して送出するように

しています。このsetXは、例外を内部で処理せずに、呼び出し元に投げるため、throws Exceptionとい

うキーワードをメソッドの宣言に記述しています。

PositiveX.java

class PositiveX {

int x;

void setX(int x) throws Exception {

if(x < 0) {

Exception e = new Exception("引数に負の値が渡されました");

throw e;

}

this.x = x;

}

}

PositiveXクラスのsetXメソッドを他のクラスから呼び出す場合、setXメソッドから投げられる例外を

受け取れるようにtry-catch構文を用いる必要があります。Example8_7.javaでは、try-catch構文の

中でsetXメソッドを呼び出しています。

class Example8_7 {

public static void main(String args[]) {

PositiveX px = new PositiveX ();

try {

px.setX(-1);

}

catch (Exception e) {

System.out.println(e);

}

}

}

実行結果は次のようになります。Exceptionクラスのコンストラクタで指定した文字列が出力されています。

java.lang.Exception: 引数に負の値が渡されました

例外を投げる可能性があるメソッドを使用する場合には、呼び出し元で、投げられるかもしれない例外に備え

て try-catch構文を使用する必要があるので注意しましょう。Javaに予め準備されているクラスのメソッ

ドの中には、例外を投げる可能性のあるものがいくつかあります。たとえば API 仕様書で

java.lang.Thread クラスの sleep メソッドを調べると、次のように記載されているので、例外を投げる

可能性があることがわかります。

public static void sleep(long millis) throws InterruptedException

メモ 上記のThreadクラスのsleepメソッドは11-4節でスレッドの扱いを学習する時に使用します。

引数で渡されたxの値が負の場合 新 し い

Exception オブ

ジェクトを生成し

ます Exceptionオブジェクトを送出します。catchブロックま

でジャンプし、この後の処理は実行されません。

x が負の値でない場合だけ実行されます

PositiveXオブジェクトのsetXメソッドに-1を渡して呼び出します

例外を受け取ります

例外の内容を出力します

例外を投げる可能性のあるメソッドであることを宣言します

Page 96: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

96

■まとめ■

・メソッドの宣言に「throws 例外の型」を記述することで、例外オブジェクトをメソッドの外へ送出するこ

とができます。

・メソッドを呼び出した側は、送出される例外オブジェクトをcatchブロックで受け取る必要があります。

練習問題

1. 次の文章の中で誤っているものを選びなさい。

(1) 例外処理とはゼロでの割り算のように、実行時に発生する可能性のある問題に対処するための仕組

みである。

(2) 例外が発生すると送出される例外オブジェクトのクラスに拠らず、必ずcatchブロック内の処理が

実行される。

(3) 例外は全てThrowableクラスのサブクラスのオブジェクトによって表現される。

(4) 例外を投げる可能性のあるメソッドを呼び出す場合は、その例外を受け止めるcatch文を用意して

おく必要がある。

2. Example8_3.java を実際に入力し、さまざまなコマンドライン引数を渡したときに、どのような結果

が出力されるか実験してみましょう。

Page 97: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

97

第 9 章 入出力

9-1 ファイルへの出力

■java.io パッケージに含まれる BufferedWriter クラスを使用することで、ファイルへ文字列を書き出

すことができます。

プログラムによっては実行結果をファイルに保存したい場合、またはファイルの内容を読み込んで処理を行い

たい場合があります。このような処理をファイルの入出力といいます。Java ではこれらの処理を行うための

便利なクラス群がjava.ioパッケージに含まれています☆。

ファイルへ文字列を出力するには、java.io.BufferedWriterクラスの writeメソッドを使用します。

そのための準備として、次の手順を行います☆。

(1) ファイルのパスを引数にしてFileWriterクラスのオブジェクトを作成する

(2) (1)で作成したFileWriterオブジェクトを引数にしてBufferedWriterクラスのオブジェクトを作

成する

Example9_1.javaは、「c:¥java¥test.txt」というファイルに"[0]"から"[4]"までの文字を書き出す

例です。

Example9_1.java

import java.io.*;

class Example9_1 {

public static void main(String args[]) {

try {

FileWriter fw = new FileWriter("c:¥¥java¥¥test.txt");

BufferedWriter bw = new BufferedWriter(fw);

for(int i = 0; i < 5; i++) {

bw.write("[" + i + "]¥n");

}

bw.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

ファイルへの出力を、上書きではなく追加にするには、FileWriter のオブジェクトの生成を次のように変

更します。

java.ioパッケージに含まれるクラスを使用することを宣言します

(ファイルが開けないなどの)例外が発生する可能性がある処理なので、try-catch構文を使用します

ファイルパスを引数にして、FileWriterクラスのオブジェクトを生成します

FileWriterクラスのオブジェクトを引数にしてBufferedWriterクラスのオブジェクトを生成します

BufferedWriterオブジェクトのwriteメソッド

を使用してファイルに文字列を書き出します

BufferedWriterオブジェクトのcloseメソッドを使用してファイルを閉じます

例外が発生した場合の処理です

Page 98: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

98

FileWriter fw = new FileWriter("c:¥¥java¥¥test.txt", true);

■まとめ■

・java.io.BufferedWriterクラスの writeメソッドを使用してファイルに文字列を書き出すことがで

きます。

・ファイルへ文字を書き出す処理は、例外が発生する可能性があるので、try-catch構文を使用します。

9-2 ファイルからの入力

■java.io パッケージに含まれる BufferedReader クラスを使用することで、ファイルの中身を読み込む

ことができます。

ファイルから文字列を 1行ずつ読み込むには、java.io.BufferedReaderクラス☆の readLineメソッ

ドを使用します。ファイルの出力同様に、準備として次の手順を行います。

(1) ファイルのパスを引数にしてFileReaderクラスのオブジェクトを作成する

(2) (1)で作成したFileReaderオブジェクトを引数にしてBufferedReaderクラスのオブジェクトを作

成する

Example9_2.javaは、「c:¥java¥test.txt」というファイルから一行ずつ読み込み、読み込んだ内容を

出力する例です。

Example9_2.java

import java.io.*;

class Example9_2 {

public static void main(String args[]) {

try {

FileReader fr = new FileReader("c:¥¥java¥¥test.txt");

BufferedReader br = new BufferedReader(fr);

String s;

while((s = br.readLine()) != null) {

System.out.println(s + "を読み込みました");

}

br.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

結果は次のようになります。前節でファイルに書き出した内容を1行ずつ読み込んでいます。

[0]を読み込みました

(ファイルが開けないなどの)例外が発生する可能性がある処理なので、try-catch構文を使用します

ファイルパスを引数にして、FileReaderクラスのオブジェクトを生成します

FileReaderクラスのオブジェクトを引数にしてBufferedReaderクラスのオブジェクトを生成します

BufferedReaderオブジェクトのcloseメソッドを使用してファイルを閉じます

BufferedReader オブジェクト

の readLine メソッドを使用し

てファイルから1行ずつ読み込ん

だ内容を文字列sに代入します

例外が発生した場合の処理です

Page 99: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

99

[1]を読み込みました

[2]を読み込みました

[3]を読み込みました

[4]を読み込みました

■まとめ■

・java.io.BufferedReaderクラスの readLineメソッドを使用してファイルの中身を 1行ずつ読み込

むことができます。

・ファイルの中身を読み込む処理は、例外が発生する可能性があるので、try-catch構文を使用します。

9-3 ファイルの内容のトークン化

■java.ioパッケージに含まれるStreamTokenizerクラスを使用することで、ファイルの中身を単語ごと

に区切って読み込むことができます。

ファイルに保存されている内容を読み取って何か処理を行うには、1 行ごとに読み込むより単語ごとに区切

って読み込んだ方が便利なことが多くあります。これは java.io.StreamTokenizer クラスを使用すると

簡単に行えます。StreamTokenizerでは、空白と改行が単語の区切りと認識されます(whitespaceChars

メソッドを使用して区切りに使う記号を後から変更することもできます)。区切られた単語 1つ 1つをトーク

ンといいます。

例題として、次のような内容のファイルをc:¥java¥token_test.txtという名前で保存し、トークンに

区切って読み込む実験を行ってみましょう。

c:¥java¥token_test.txt

123 456 789

123, 456, 789

12.3 45.6 78.9

abc def ghi-jkl

StreamTokenizerオブジェクトを生成するには、コンストラクタに前節で示したBufferedReadrオブ

ジェクトを渡します。StreamTokenizerオブジェクトのnextTokenメソッドを呼び出すと、入力ストリー

ムから次の単語を取り出し、取り出した単語がどのような種類のものであるかを示す値が戻り値となります。

また、その値は変数 ttype にも設定されます。読み取った内容は、その単語が数値を表す場合はオブジェク

トの変数nvalに、文字列の場合はsvalに格納されます。

ttypeの値と読み取った内容の種類の関係は表9-1のようになります。

表9-1. StreamTokenizerクラスのttypeの値と読み取った内容の関係

ttypeの値 読み取った内容の種類 読み取った内容の取得方法

StreamTokenizer.TT_WORD 文字単語 svalから文字列を取得する

StreamTokenizer.TT_NUMBER 数字 nvalからdouble値を取得する

StreamTokenizer.TT_EOL 行の終わり (初期設定ではこの値は使用されません)

StreamTokenizer.TT_EOF データの終わり

上記以外 上記以外 ttypeから一文字を取得する

Example9_3.javaはStreamTokenizerを試用してtoken_test.txtファイルの中のトークンを区切

Page 100: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

100

って読み取る例です。

Example9_3.java

import java.io.*;

class Example9_3 {

public static void main(String args[]) {

try {

FileReader fr = new FileReader("c:¥¥java¥¥token_test.txt");

BufferedReader br = new BufferedReader(fr);

StreamTokenizer st = new StreamTokenizer(br);

while(st.nextToken() != StreamTokenizer.TT_EOF) {

switch(st.ttype) {

case StreamTokenizer.TT_WORD:

System.out.println("文字トークン" + st.sval);

break;

case StreamTokenizer.TT_NUMBER:

System.out.println("数値トークン" + st.nval);

break;

default:

System.out.println("その他のトークン" + (char)st.ttype);

break;

}

}

br.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

実行結果は次のようになります。例題として使用したtoken_test.txtの内容と見比べてみましょう。

数値トークン123.0

数値トークン456.0

数値トークン789.0

数値トークン123.0

その他のトークン,

数値トークン456.0

その他のトークン,

Example9_2.javaと同じようにBufferedReaderオブジェクトを生成します

実験に使用するファイル名を指定します

BufferedReaderオブジェクトを引数にしてStreamTokenizerクラスのオブジェクトを生成します

トークンの種類が文字でも数字でもない場合

トークンの種類が数字の場合

トークンの種類が文字の場合

トークンの種類に応じて処理を分岐させます

次のトークンを読み取り、ファイルが終了するまで処理を繰り返します

1行目が3つの数値として読み取られています。

2行目が3つの数値と2つの「その他のトークン」として読み取られています。カ

ンマ(,)がその他のトークンとして認識されています。

Page 101: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

101

数値トークン789.0

数値トークン12.3

数値トークン45.6

数値トークン78.9

文字トークンabc

文字トークンdef

文字トークンghi-jkl

■まとめ■

・java.io.StreamTokenizerクラスのnextTokenメソッドを使用して、ファイルの中身を1単語ずつ区

切って読み込むことができます。

・StreamTokenizerに含まれるメソッドの詳しい内容については、API仕様書を参照しましょう。

練習問題

1. 1から50までに含まれる3の倍数をファイルに書き出すプログラムを作ってみましょう。

2. ファイルを読み込んで、行の先頭に行番号をつけて出力するプログラムを作ってみましょう。

3. 次の内容のファイル(data.txt)を読み込んで、ファイル内の数字を足し合わせた結果を出力するプロ

グラムを作って見ましょう。

12 33 56 22 34 44 12 43 9 19 73

4行目が3つの文字単語として読み取られています。「-」もアルファベ

ットと同じように扱われています。

3行目が3つの数値として読み取られています。ピリオド(.)が小数点

として認識されています。

Page 102: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

102

第 10 章 アプレットの基本

10-1 初めてのアプレット

■ Webブラウザ上で実行できるJavaプログラム、アプレットを作成します。

アプレットとは、Internet Explorer(インターネットエクスプローラ)やNetscape Navigator(ネ

ットスケープナビゲータ)などのWebブラウザ上で実行できるJavaプログラムです。HTMLだけで記述され

たページには動きがありませんが、アプレットによって対話的な動作、グラフィック描画などの機能を追加す

ることができます(最近ではFlashやDHTMLなど、Javaアプレット以外にも対話的な操作を可能にする技

術が複数あります)。

何も動作しないアプレットがjava.appletパッケージに含まれるAppletクラスに定義されています。こ

のAppletクラスがアプレットの基本となります。何も動作しないのでは意味が無いので、実際にはApplet

クラスを継承するサブクラスを新しく作成し、必要な機能を追加することになります(継承については6章で

説明しています)。

Example10_1.javaはアプレットの中央に「Hello!」という文字列を出力する例です。

Example10_1.java

import java.applet.Applet;

import java.awt.Graphics;

public class Example10_1 extends Applet {

public void paint(Graphics g) {

g.drawString("Hello!", 100, 100);

}

}

Example10_1.java では、まずはじめに import 文でコード内で使用するクラスの宣言を行っています

(7-5 節参照)。この例では、java.applet パッケージの Applet クラスと java.awt パッケージの

Graphicsクラスを使用します。次に、extendsキーワードを使用してAppletクラスを継承することを宣

言します。アプレットの描画は、paintメソッドで行われるので、このメソッドをオーバーライド(6-3節参

照)して、独自の描画処理を定義します。paintメソッドでは、引数にjava.awt.Graphicsクラスの☆オ

ブジェクトが渡されるので、このオブジェクトを利用して描画を行います。GraphicsクラスのdrawString

メソッドを使用することで、文字列をアプレットに描画できます。

なお、ここで作成したアプレットは、今まで学習したようなjavaコマンドで実行することはできません。

実行の仕方は次の節で説明します。

メモ アプレットを作成する場合は、クラスの宣言にpublic修飾子をつける必要があります。また、public

修飾子が付くクラスを定義したコードは、必ず「クラス名.java」という名前で保存する必要があります。

■まとめ■

・アプレットとは、Webブラウザ上で実行できるJavaプログラムです。

java.appletパッケージのAppletクラスを使用します

描画のためにjava.awtパッケージのGraphicsクラスを使用します

Appletクラスを継承します

Appletクラスのpaintメソッドをオーバーライドします

paintメソッドの引数で渡された Graphicsオブ

ジェクトのdrawStringメソッドを使用します

Page 103: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

103

・java.applet.Appletクラスを継承するクラスを作成し、必要な機能を追加します。

・アプレットの描画はpaintメソッドで行われます。

10-2 アプレットの実行

■アプレットをWebブラウザとアプレットビューアで実行します。

◆Webブラウザでの実行

インターネットエクスプローラなどのWebブラウザは、HTMLというWebページ用の言語が書かれたファイ

ルを読み込んでページを表示します。ブラウザ上にアプレットを表示するには、このHTML文に「アプレット

を表示しなさい」という命令(HTMLタグ)を記述する必要があります。このタグは次のように記述します。

<applet code="アプレットのクラス名" width=アプレットの幅 height=アプレットの高さ>

</applet>

Example10_1.htmlは、前節で作成したExample10_1という名前のアプレットを表示するHTML文の例

です。

Example10_1.html

<html>

<body>

<h1>はじめてのアプレット</h1>

<applet code="Example10_1" width=300 height=300>

</applet>

</body>

</html>

Example10_1.java を コ ン パ イ ル し て 生 成 さ れ る Example10_1.class フ ァ イ ル と

Example10_1.htmlを同じディレクトリに配置し、htmlファイルをブラウザで開くと、図10-1のように、

アプレットが実行された様子が表示されます。

メモ アプレットのクラスファイルとHTMLファイルは同じディレクトリに保存する必要があります。

アプレットを表示するため

のタグです

Page 104: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

104

図10-1.アプレットをブラウザで実行した様子

HTML 文に<applet>のタグが含まれていると、そのページが表示される時に、ブラウザが自動的にクラス

ファイルをダウンロードし、アプレットが実行されます。

メモ 今まで作成したクラスの場合、javaコマンドを実行すると自動的に mainメソッドが処理されました。

アプレットの場合はappletviewerまたはWebブラウザによって自動的に実行されるメソッドが複数存在し

ます。そのうちの一つがpaintメソッドで、アプレットが描画されるときに自動的に実行されます。

◆アプレットビューアでの実行

アプレットはWebブラウザ上で動作すると書きましたが、Webブラウザを起動しなくてもアプレットの動作

を確認できる「アプレットビューア」というツールがあります。これはJDKと共に自動的にインストールされ

るため、付録の方法でJDKをインストールした場合は次のようにコマンドプロに入力して起動できます。

appletviewer HTML文を記述したファイル

前節の Example10_1.htmlがあるディレクトリで次のように入力すると、アプレットビューアが起動し、

作成したアプレットが表示されます(図10-2)。

appletviewer Example10_1.html

図10-2.アプレットビューアでの実行

■まとめ■

・アプレットを実行するには、そのためのHTMLタグを記述したファイルを準備する必要があります。

・アプレットはWebブラウザまたはアプレットビューアで実行することができます。

10-3 アプレットのグラフィック

■アプレットのpaintメソッドにはGraphicsオブジェクトが渡されます。このGraphicsオブジェクトに

定義されている様々なメソッドを使ってグラフィック描画を行えます。

◆paintメソッド

アプレットのグラフィック描画は paint メソッドによって行われます。paint メソッドには引数として

Page 105: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

105

Graphicオブジェクトが渡されるので、このオブジェクトを使用して描画処理を行います。Graphics☆クラ

スには多くの描画メソッドが準備されています。

◆座標系

アプレットで使用されるGraphicsクラスの座標系は、原点(0, 0)が左上で、x座標軸は画面の右方向、

y座標軸は画面の下方向になっています(図10-3)。

図10-3. アプレットの座標系

右下隅の座標値はアプレットの大きさによって異なります。アプレットの大きさは、ブラウザまたはアプレ

ットビューアによって決定されます。アプレット表示用のタグを次のように記述した場合、右下隅の座標値は

(400, 200)となります。

<applet code="appletName" width=400 height=200>

</applet>

メモ 座標値の単位は画面のピクセル数です。一般的なパソコンの画面の解像度は1024×768ピクセル程度な

ので、これより大きな値はアプレットのサイズに指定しないようにしましょう。

◆直線の描画

Graphicsクラスの drawLineメソッドを使用して直線を描画できます。drawLineメソッドでは、直線

の始点と終点の座標を次のように4つの引数で指定します。

drawLine(始点のx座標, 始点のy座標, 終点のx座標, 終点のy座標);

Example10_2.javaは、3本の直線を描画する例です。

Example10_2.java

import java.applet.Applet;

import java.awt.Graphics;

/*

<applet code="Example10_2" width=300 height=300>

</applet>

*/

public class Example10_2 extends Applet {

public void paint(Graphics g) {

アプレットビューア

で実行できるよう

に、コメント文の中

に<applet>タグを

記述します

Page 106: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

106

g.drawLine(50, 50, 250, 50);

g.drawLine(50, 50, 250, 250);

g.drawLine(50, 50, 50, 250);

}

}

アプレットをブラウザで実行するための Webページは.htmlという拡張子の別ファイルに保存する必要が

ありますが、アプレットビューアで実行する場合は<applet>タグさえ記述されていれば拡張子は何でも構い

ません。そこで、コードにコメント文で<applet>タグを記述しておけば、コードを記述したファイルをアプ

レットビューアで開くことができます。これにより、アプレットのコード(.javaファイル)とアプレットを

表示するためのHTML(.htmlファイル)の2つを別々に管理する手間を省くことができます。

Example10_2.javaでは、/*と*/で囲まれたコメント文の中に<applet>タグを記述しているので、次の

ように、Example10_2.javaを指定してアプレットビューアを起動できます。

appletviewer Example10_2.java

Example10_2.javaの実行結果は図10-4のようになります。

図10-4. Example10_2の実行結果

◆描画色の変更

Graphicsオブジェクトは、初期状態で描画色が黒に設定されています。描画色を変更するには、次に示す

GraphicクラスのsetColorメソッドを使用します。

void setColor(Color c)

setColorメソッドには、引数にColorクラスのオブジェクトを渡します。特定の色を表すColorクラス

のオブジェクトが表10-1のように予め準備されているため、これらを使用して色を指定できます。

表10-1. Colorクラスに準備されている色

色 指定方法

白 Color.white

薄い灰色 Color.lightGray

灰色 Color.gray

濃い灰色 Color.darkGray

GraphicsオブジェクトのdrawLineメソッ

ドを使って直線を描画します

Page 107: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

107

黒 Color.black

赤 Color.red

ピンク Color.pink

オレンジ Color.orange

黄 Color.yellow

緑 Color.green

シアン Color.cyan

青 Color.blue

マゼンタ Color.magenta

メモ Colorクラスには、R(赤)、G(緑)、B(青)に0~255の値を指定することで任意の色を表すオブジェク

トを生成できるコンストラクタがあります。例えば、R、G、Bの値がすべて 0だと黒になり、すべて 255だ

と白になります。このコンストラクタを使用することで、表10-1以外にも任意の色を作成できます。

Example10_3.java は描画色を赤に指定して長方形の描画を行う例です。長方形は Graphics クラスの

fillRectメソッドを使って描画できます。

fillRect(左上隅のx座標, 左上隅のy座標, 横の長さ, 縦の長さ);

メモ API仕様書でGraphicsクラスのsetColorメソッドとfillRectメソッド、Colorクラスのコンス

トラクタをそれぞれ調べてみましょう。

Example10_3.java

import java.applet.Applet;

import java.awt.*;

/*

<applet code="Example10_3" width=300 height=300>

</applet>

*/

public class Example10_3 extends Applet {

public void paint(Graphics g) {

g.setColor(Color.red);

g.fillRect(50, 50, 200, 200);

}

}

Example10_3.javaを実行した結果は図10-5のようになります。

描画色を赤に設定します

左上隅が(50, 50)、幅と高さが200の長方形を描画します

java.awt.Graphicsクラスとjava.awt.Colorクラスを使用するので、

アスタリスク(*)をつけて、まとめてimport宣言をしています

Page 108: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

108

図10-5. Example10_3の実行結果

◆アプレットサイズの取得

アプレットのサイズは<applet>タグの中で好きな大きさに指定することができました。ブラウザやアプレ

ットビューアはタグの中で指定された大きさでアプレットを表示します。したがって、コードを作成している

時点では、作成したアプレットのサイズを知ることができません。アプレットの大きさに応じて表示する内容

を変えるには、実行時に大きさを取得する必要があります。

アプレットでは次のようにgetSizeメソッドを使って自分自身の大きさを知ることができます。

Dimension d = getSize();

幅と高さはDimensionクラスの変数widthとheightに格納されるため、次のようにして幅と高さを取

得できます。

int width = d.width;

int height = d.height;

Example10_4.javaはアプレットの大きさを取得し、それを元に全体の4分の1の大きさの長方形を描画

する例です。

Example10_4.java

import java.applet.Applet;

import java.awt.*;

/*

<applet code="Example10_4" width=300 height=300>

</applet>

*/

public class Example10_4 extends Applet {

public void paint(Graphics g) {

Dimension d = getSize();

int width = d.width;

int height = d.height;

g.fillRect(0, 0, width/2, height/2);

アプレットのサイズを取得します

アプレットの幅を取得します

アプレットの高さを取得します

左上隅が(0, 0)で幅と高さがそれぞれアプレ

ットサイズの半分の長方形を描画します

この値でアプレットのサイズを変更できます

Page 109: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

109

}

}

Example10_4.javaをアプレットビューアで実行した結果は図10-6のようになります。左右でアプレッ

トの大きさが異なりますが、どちらも全体の4分の1の大きさの長方形が描画されています(アプレットのサ

イズは<applet>タグで指定できます。アプレットビューアで表示しているときは、ウィンドウの枠をマウス

でドラッグしてもサイズを変更できます)。

図10-6. サイズを変えてExample10_4を実行した結果

◆Graphicsクラスの様々な描画メソッド

Graphicsクラスには、今まで見てきたような文字や直線、長方形の描画以外にも、様々なメソッドが用意

されています。主なものに表10-2に示すメソッドがあります。これらのメソッドを活用して、いろいろなも

のを描画してみましょう。その他の詳細はAPI仕様書を参照してください。

表10-2.Graphicsクラスの主なメソッド

メソッド 説明

void drawArc(int x, int y, int w, int h,

int degrees0, int degrees1)

左上隅を(x, y)、幅と高さを w, h とする四角形に

内接する円の一部を描画する。描画する範囲は

degrees0とdegrees1の角度で指定する(0度は時

計の3時に場所に相当)。

void drawLine(int x0, int y0, int x1, int

y1)

(x0, y0)の点と(x1, y1)の点を結ぶ線分を描画す

る。

void drawOval(int x, int y, int w, int h) 左上隅を(x, y)、幅と高さを w, h とする四角形に

内接する楕円を描画する

void drawPolygon(int x[], int y[], int n) n個の頂点を持つ多角形を描画する。頂点の座標は配

列xとyの要素で指定する。

void drawPolyline(int x[], int y[], int

n)

n個の頂点を持つ折れ線を描画する。頂点の座標は配

列xとyの要素で指定する。

void drawRect(int x, int y, int w, int h) 左上隅を(x, y)、幅と高さを w, h とする四角形を

描画する

void drawString(String str, int x, int y) 文字列strを(x, y)の位置に描画する

void fillArc(int x, int y, int w, int h, drawArcと同じ要領で指定される弧を塗りつぶす。

Page 110: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

110

int degrees0, int degrees1)

void fillOval(int x, int y, int w, int h) drawOval と同じ要領で指定される楕円を塗りつぶ

す。

void fillPolygon(int x[], int y[], int n) drawPolygonと同じ要領で指定される多角形を塗り

つぶす。

void fillRect(int x, int y, int w, int h) drawRect と同じ要領で指定される四角形を塗りつ

ぶす。

Color getColor() 現在の描画色を取得する

Font getFont() 現在のフォントを取得する

void setColor(Color c) 描画色を設定する

void setFont(Font f) フォントを設定する

■まとめ■

・アプレットのグラフィック描画はpaintメソッドに渡されるGraphicsオブジェクトを使用して行います。

・Graphicsクラスには、直線、円弧、楕円、長方形などを描画するメソッド、色を設定するメソッドなど便

利なメソッドがたくさん準備されています。

練習問題

丸や四角の組み合わせで好きな絵をアプレットに描いてみましょう。Example10_3.javaや表10_2、API

仕様書などを参考にしましょう。

Page 111: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

111

第 11 章 アプレットの応用

11-1 アプレットのマウス操作

■ ユーザーによってマウスがクリックされることや、アプレット上のボタンが押されることなどをイベント

といいます。ユーザーの操作によってアプレットの動作を切り替えるには、このイベントを受け取って処理し

ます。

◆イベントとは

ユーザーによってマウスがクリックされることや、アプレット上のボタンが押されることなどをイベントと

いい、そのような動作が行われることを「イベントが発生する」といいます。このようなイベントが発生した

時の命令をコードに組み込むことで、ユーザーの操作によって処理を切り替える対話的なアプレットを作成す

ることができます。

イベントの処理が行われる際には、イベントを発生する「ソース」から、そのイベントを受け取る「リスナ

(listener)」へイベント通知が行われます。

このイベント通知を受け取って、イベントが発生した時の処理をアプレットに組み込むには、次の2つの手

順が必要になります。

(1) リスナインターフェイスの実装:イベントを受け取るためのリスナインターフェイスをアプレットに

実装します

(2) ソースへのリスナ登録:ソースからのイベント通知をアプレットが受け取る(リスナになる)ことを

登録します

◆マウスクリック

マウスがクリックされた時に発生するイベントをアプレットで受け取り、その時に特定の命令を実行するに

は前節で述べた2つの手順を行います。具体的には次のようにします。

(1) リスナインターフェイスの実装

MouseListener インターフェイスを実装します。MouseListener インターフェイスには次の 5

つのメソッドが定義されているので、全てのメソッドをアプレットに追加し、必要に応じて処理を記述

します。

・void mouseClicked(MouseEvent e) マウスがクリックされた時に呼ばれます

・void mouseEntered(MouseEvent e) マウスがアプレット領域に入った時に呼ばれます

・void mouseExited(MouseEvent e) マウスがアプレット領域外に出た時に呼ばれます

・void mousePressed(MouseEvent e) マウスボタンが押された時に呼ばれます

・void mouseReleased(MouseEvent e) マウスボタンが放された時に呼ばれます

(2) ソースへのリスナ登録

アプレットが起動した時に実行される initメソッドで addMouseListnerメソッドを使用してア

プレット自身を登録します。

以上の手続きを行うことで、ユーザーのマウスクリックにでアプレットの操作を行えるようになります。

Example11_1.java は、この MouseListener インターフェイスを実装して、マウスがクリックされた場

所に円を描画するアプレットの例です。

Page 112: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

112

メモ アプレットが起動すると、まず始めにinitメソッドが実行されます。また、Appletクラスのrepaint

メソッドはアプレットの再描画を行います。マウスクリックなどのイベントが発生した座標は MouseEvent

クラスの getX, getYメソッドで取得できます。それぞれのメソッドについて、API仕様書で調べてみまし

ょう。

Example11_1.java

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

/*

<applet code="Example11_1" width=300 height=300>

</applet>

*/

public class Example11_1 extends Applet implements MouseListener {

int x = 150;

int y = 150;

public void init() {

setBackground(Color.white);

addMouseListener(this);

}

public void paint(Graphics g) {

g.setColor(Color.red);

g.fillOval(x – 10, y – 10, 20, 20);

}

public void mouseClicked(MouseEvent e) {

x = e.getX();

y = e.getY();

repaint();

}

public void mouseEntered(MouseEvent e) {

setBackground(Color.white);

repaint();

}

public void mouseExited(MouseEvent e) {

setBackground(Color.blue);

repaint();

}

public void mousePressed(MouseEvent e) { }

public void mouseReleased(MouseEvent e) { }

}

まず最初に実行されるメソッドです

背景色を白に設定します

イベントソースに自分自身をリスナ登録します

MouseListenerインターフェイスを実装します

インスタンス変数にxとyを定義します。この値をマウスクリックされた座標

値を記憶しておくために使用します

描画色を赤に設定します

縦横の大きさが20の円を描画します

マウスクリック時に呼ばれます

マウスがアプレット領域に入った時

に呼ばれます

マウスがアプレット領域から出た時

に呼ばれます

マウスが押された時に呼ばれます

マウスが放された時に呼ばれます

クリックした時の座標値を変数x, yに代入します

再描画します

再描画します

再描画します

背景色を白に設定します

背景色を青に設定します

Page 113: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

113

Example11_1を実行した結果は図11-1のようになります。マウスクリックした場所に赤い丸が描画され

ます。マウスカーソルがアプレットの外に出ると、背景が青になります。

図11-1. Example11_1の実行結果

◆マウスの移動とドラッグ

マウスが移動したときとドラッグされた時に発生するイベントをアプレットで受け取り、その時に特定の命

令を実行するには、マウスのクリックと同様に前節で述べた2つの手順を行います。具体的には次のようにし

ます。

(1) リスナインターフェイスの登録

MouseMotionListenerインターフェイスを実装します。MouseMotionListenerインターフェイ

スには次の2つのメソッドが定義されているので、両方メソッドをアプレットに追加し、必要に応じて

処理を記述します。

・void mouseDragged(MouseEvent e) マウスがドラッグされた時に呼ばれます

・void mouseMoved(MouseEvent e) マウスが移動した時に呼ばれます

(2) ソースへのリスナ登録

アプレットが起動時に実行される initメソッドで addMouseMotionListnerメソッドを使用して

アプレット自身を登録します。

以上の手続きを行うことで、ユーザーのマウス移動とドラッグに応じたアプレットの操作を行えるようにな

ります。Example11_2.java は、この MouseListener インターフェイスを実装して、マウスカーソルの

座標値を出力するアプレットの例です。

メモ アプレットでSystem.out.printlnメソッドを使用すると、アプレットビューアを起動したコマンド

ラインに文字列が出力されます。インターネットブラウザでアプレットを起動している場合は「Java コンソ

ール」で出力内容を見ることができます。

Example11_2.java

import java.applet.*;

import java.awt.event.*;

/*

Page 114: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

114

<applet code="Example11_2" width=300 height=300>

</applet>

*/

public class Example11_2 extends Applet implements MouseMotionListener {

public void init() {

addMouseMotionListener(this);

}

public void mouseMoved(MouseEvent e) {

System.out.println("マウスが動きました x="

+ e.getX() + ",y=" + e.getY());

}

public void mouseDragged(MouseEvent e) {

System.out.println("マウスがドラッグされました x="

+ e.getX() + ",y=" + e.getY());

}

}

Example11_2.javaを実行すると、何も描画されないアプレットが現れます。アプレットビューアをコマ

ンドプロンプトから起動した場合、アプレット上でマウスカーソルを動かしたりドラッグを行うと、次のよう

な文字列が出力されます。

マウスが動きました x=196,y=124

マウスが動きました x=196,y=123

マウスが動きました x=196,y=122

マウスがドラッグされました x=196,y=123

マウスがドラッグされました x=196,y=124

マウスがドラッグされました x=195,y=124

メモ マウスのクリックとドラッグの両方のイベントの通知を受け取るには、MouseListener と

MouseMotionListenerの両方のインターフェイスを実装します。

■まとめ■

・ユーザーがマウスをクリックしたりドラッグするとイベントが発生します。

・イベントを受け取るには、リスナインターフェイスの実装と、ソースへのリスナ登録が必要です。

・マウスがクリックされた時に発生するイベントを受け取るには、MouseListenerインターフェイスを実装

し、addMouseListnerメソッドでリスナ登録を行います。

・マウスが移動・ドラッグされた時に発生するイベントを受け取るには、MouseMotionListenerインター

フェイスを実装し、addMouseMotionListnerメソッドでリスナ登録を行います。

MouseMotionListenerインターフェイスを実装します

まず最初に実行されるメソッドです

イベントソースに自分自身をリスナ登録します

マウスが動いた時に呼ばれます

マウスがドラッグされた時に呼ばれます

マウス座標を出力します

マウス座標を出力します

Page 115: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

115

11-2 AWTの使用

■ボタンやチェックボックスなどのGUI(グラフィカルユーザーインターフェイス)を用いたアプレットを作

成します。

◆AWTとは

AWTとはAbstract Window Toolkitの略で、ボタンやチェックボックスなどのGUI(グラフィカルユー

ザーインターフェイス)を提供するツール群のことをいい、予めJavaの標準的なライブラリとして準備され

ています。これらを使用することで、簡単なコードでGUIの実装を実現できます。

Javaは Windowsや Macintoshでも動作するしますが、ボタンなどの GUIツールの形状は OSごとに異

なります。AWTではOSに依存したGUIを用いるため、「機能」は同じでも「外観」は異なります。そのため、

AWTでは厳密に外観を定義できないという制約があります。

メモ 本書では取り上げませんが、環境に依存しないGUIを提供するライブラリとしてSwingとういものがあ

ります。

◆AWTの使用

AWT に準備されているツールには、ボタン、チェックボックス、ラベル、スクロールバーなどがあります。

これらをアプレットに追加するには、次の2つの手順を行います。

(1) GUIオブジェクトの作成:ボタンやチェックボックスなどのGUIツールオブジェクトを生成します。

(2) GUIオブジェクトの追加:(1)で作成したオブジェクトをaddメソッドを使用してアプレットに乗せ

ます。

上記の2つの手順はそれぞれ、アプレットの初期化時に行われるようにinitメソッドの中で行います。

Example11_3.javaは、アプレットで使用できる主なGUIオブジェクトを乗せた例です。

Example11_3.java

import java.applet.*;

import java.awt.*;

/*

<applet code="Example11_3" width=400 height=300>

</applet>

*/

public class Example11_3 extends Applet {

public void init() {

Label label = new Label("ラベル");

add(label);

Button button = new Button("ボタン");

add(button);

Checkbox checkbox = new Checkbox("チェックボックス");

add(checkbox);

ラベルオブジェクトを作成します

作成したラベルをアプレットに乗せます

ボタンオブジェクトを作成します

作成したボタンをアプレットに乗せます チェックボックスオブジェク

トを作成します

作成したチェックボックスをアプレットに乗せます

Page 116: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

116

Choice choice = new Choice();

choice.addItem("チョイス 項目1");

choice.addItem("チョイス 項目2");

choice.addItem("チョイス 項目3");

add(choice);

TextField textField = new TextField(20);

add(textField);

TextArea textArea = new TextArea(10,20);

add(textArea);

List list = new List();

list.add("リスト 項目1");

list.add("リスト 項目2");

list.add("リスト 項目3");

add(list);

Scrollbar scrollbar = new Scrollbar(Scrollbar.HORIZONTAL, 5, 1, 0, 10);

add(scrollbar);

}

}

Example11_3.javaを実行した結果は図11-3のようになります。簡単なコードで便利なGUIオブジェク

トをアプレットに追加できたことを確認できます。

しかし、Example11_3.javaでは、オブジェクトをアプレットに乗せただけなので、ボタンを押したりス

クロールバーを動かしても何も反応はありません。これらのGUIオブジェクトに対する操作によってアプレッ

トの処理を切り替えるには、マウス操作のときと同じような「イベント処理」のためのコードを記述する必要

があります。この方法については次節で説明します。

チョイスオブジェクトを作成します

チョイスオブジェクトに項目を追加します

作成したチョイスをアプレットに乗せます

作成したテキストフィールドをアプレットに乗せます

作成したテキストエリアをアプレットに乗せます

作成したリストをアプレットに乗せます

作成したスクロールバーをアプレットに乗せます

テキストフィールドオブジェ

クトを作成します

テキストエリアオブジェクトを作成します

リストオブジェクトに項目を追加します

リストオブジェクトを作成します

スクロールバーオブジェクトを作成します

Page 117: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

117

図11-3.Example11_3の実行結果

メモ Example11_3.javaに出てくる Labelや Buttonなどの各クラスのコンストラクタを API仕様書で

調べてみましょう。

◆AWTのイベント処理

マウス操作同様、ユーザーがボタンをクリックするなどの動作を行うとイベントが発生します。このイベン

ト通知をアプレットで受け取るためには前節で説明したマウスによる操作と同様に、「リスナイターフェイスの

実装」と「リスナの登録」を行います。ボタンが押された時のイベントを受け取るには、ActionListener

インターフェイスを実装し、ボタンオブジェクトのaddActionListenerメソッドを利用してリスナ登録を

行います。

Example11_4javaは、ボタンが押された時のイベントを受け取る例です。

Example11_4.java

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

/*

<applet code="Example11_4" width=300 height=100>

</applet>

*/

ラベル

ボタン チェックボックス

スクロールバー

チョイス

リスト

テキストエリア

テキストフィールド

ActionListenerインターフェイスを実装します

Page 118: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

118

public class Example11_4 extends Applet implements ActionListener {

public void init() {

Button button = new Button("ボタン");

button.addActionListener(this);

add(button);

}

public void actionPerformed(ActionEvent ae) {

System.out.println("イベントを受け取りました");

System.out.println(ae.toString());

}

}

図11-4.Example11_4の実行結果

Example11_4.javaを実行すると図11-4のようなアプレットが表示され、ボタンを押すと次のように出

力され、ボタンが押されたイベント通知を受け取っていることが確認できます。

イベントを受け取りました

java.awt.event.ActionEvent[ACTION_PERFORMED,cmd=ボタン,when=1108795207975,

modifiers=] on button0

Example11_3の例で使用したような、ボタン以外のAWTオブジェクトのイベント通知を受け取りたい場合

は、それぞれのオブジェクトに対応したインターフェイスを実装し、イベントリスナに登録する必要がありま

す。使用するインターフェイスや、イベントリスナに登録するためのメソッドは、必要に応じてAPI仕様書を

調べましょう。例えば、スクロールバーをユーザーが動かした場合に発生するイベント通知を受け取るには、

API仕様書のjava.awt.Scrollbarクラスの説明を調べます。それにより、AdjustmentListenerイン

ターフェイスを実装し、addAdjustmentListenerメソッドでリスナの登録を行う必要があることがわかり

ます。AdjustmentListener インターフェイスを実装することで追加する必要のあるメソッドについては、

さらにAdjustmentListenerについて調べましょう。

■まとめ■

・JavaにはボタンやチェックボックスなどのGUIオブジェクトを簡単に使用できるクラスがjava.awtパッ

ケージに準備されています。

・GUIオブジェクトを使うには、作成したオブジェクトをアプレットに追加し、イベント処理のためのインタ

ーフェイスを実装し、さらにリスナ登録を行います。

ボタンオブジェクトを作成します

作成したボタンオブジェクトをアプレットに乗せます

ボタンオブジェクトのイベントリスナに自身を登録します

ボタンが押されたときに呼び出されます

引数で渡された ActionEventオブジェクトの

内容を出力します

Page 119: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

119

11-3 アニメーション表示

■ スレッドを使用して、アプレットの描画内容を一定時間ごとに少しずつ変化させることで、アニメーション

表示を行えます。

アプレットの描画内容を一定時間ごとに少しずつ変化させることでアニメーション表示を行うことができま

す。このように、一定時間経過ごとに特定の処理(例えば描画内容の更新)を実行するには、スレッドを使用

します。スレッドとは、異なる複数の処理を同時並行で実行するためにJavaに備わっている仕組みです。ス

レッドの扱いには難しい概念が含まれますので、ここでは簡単にアプレットでアニメーション表示を行うため

の方法を実例で示します。この実例を元に、必要な箇所を変更することで独自のアニメーション表示を行うア

プレットを作成できます。

アプレットでスレッドを使用するには Runnable インターフェースを実装します。Runnable インターフ

ェースを実装する際には、アプレットにrunメソッドを定義する必要があります。

スレッドを用いてアニメーション表示を行うアプレット(一定時間ごとに描画内容を更新するアプレット)

を作成する場合の雛形を Example11_5.java に示します。この例の【1】~【3】に必要に応じた処理を記

述します。

Example11_5.java

import java.applet.*;

import java.awt.*;

/*

<applet code="Example11_5" width=300 height=300>

</applet>

*/

public class Example11_5 extends Applet implements Runnable {

Thread thread;

public void init() {

thread = new Thread(this);

thread.start();

}

public void run() {

try {

while(true) {

repaint();

Thread.sleep(1000);

}

【1】初期化処理を記述します

【2】一定時間ごとに行う処理を記述します

スレッド型のオブジェクトを格納するための変数です

スレッド型のオブジェクトを生成します

スレッドを開始します。これにより、runメソッドが実行されます。

アプレットの描画を行います

1000ミリ秒間処理を停止します

ループによって繰

り返されます

Page 120: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

120

} catch(Exception e) {}

}

public void paint(Graphics g) {

}

}

アプレットが起動するときにinitメソッドが実行されるため、【1】の箇所に初期化を行う処理を記述しま

す。続いてrunメソッドが実行されます。runメソッドには無限ループ処理を入れることで、アプレットが起

動している間に繰り返し行われる処理を記述できます。ここにミリ秒単位で何も処理を行わない待機時間を指

定するThread.sleepメソッドを記述することでアニメーションの再描画の間隔を指定できます。この【2】

の箇所に、一定時間経過ごとに行う処理を記述します。【3】には今まで学習した、アプレットの描画処理を記

述します。

Example11_6.javaは、上の雛形を利用して四角形が左から右へ移動する様子をアニメーション表示する

アプレットの例です。実行結果は図11-5のようになります。

Example11_6.java

import java.applet.*;

import java.awt.*;

/*

<applet code="Example11_6" width=300 height=300>

</applet>

*/

public class Example11_6 extends Applet implements Runnable {

int x = 0;

Thread thread;

public void init() {

thread = new Thread(this);

thread.start();

}

public void run() {

try {

while(true) {

repaint();

Thread.sleep(100);

x += 5;

if(x > 295) {

x = 0;

【3】描画処理を記述します

四角形を描画するx座標を保持するための変数です

xの値を5だけふやします。四角形が右端に到達したら左端に戻

るようにxを0に戻します。

Page 121: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

121

}

}

} catch(Exception e) {}

}

public void paint(Graphics g) {

g.fillRect(x, 100, 100, 100);

}

}

...

図11-5. Example11_6の実行結果

■まとめ■

・スレッドを用いることで、一定時間ごとに特定の処理を行うアプレットを作成できます。

・スレッドを用いるには、Runnableインターフェイスを実装し、runメソッドを定義します。

11-4 ダブルバッファリング

■ダブルバッファリングを用いることで、アニメーション描画時の画面のちらつきを防ぐことができます。

アプレットでは、再描画のたびに背景色でアプレット領域を塗りつぶし、改めて paint メソッドで定義さ

れている描画命令が実行されます。そのため、前節で示した方法でアニメーション表示を行うと、画面がちら

ついてしまったり、もっと複雑な描画命令を実行しようとした場合、描画の途中段階が表示されてしまったり

することがあります。これは、再描画の際に一度画面を背景色で塗りつぶす処理が行われているのと、描画が

完了する前に表示が行われてしまうことがある、という2つのことが原因となっています。

背景色で塗りつぶす処理はupdateメソッドで行われるので次のコードに追加することでupdateメソッド

をオーバーライドして背景色で塗りつぶす処理を無くすことができます。

public void update(Graphics g){

paint(g);

}

次に、表示画面と同じ大きさのImageオブジェクトを作成して、描画はこのImageオブジェクトに行うよ

うにします。このImageオブジェクトへの描画が終わった段階で、このImageオブジェクトを画面に表示す

ることで、描画の途中段階が表示される問題が解決します。このように、実際に表示される画面とは別のとこ

左上隅が(x, 100)、大きさが100の四角形を描画します

Page 122: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

122

ろ(バッファ)で描画処理を行い、その結果を画面に転送することをダブルバッファリングと言います。

Example11_7.javaは、Example11_6.javaと同じアニメーションを、ダブルバッファリングを使用し

て表示するアプレットの例です。

Example11_7.java

import java.applet.*;

import java.awt.*;

/*

<applet code="Example11_7" width=300 height=300>

</applet>

*/

public class Example11_7 extends Applet implements Runnable {

int x = 0;

Thread thread;

Image buffer;

public void init() {

Dimension d = getSize();

buffer = createImage(d.width, d.height);

thread = new Thread(this);

thread.start();

}

public void run() {

try {

while(true) {

repaint();

Thread.sleep(100);

x += 5;

if(x > 295) {

x = 0;

}

}

} catch(Exception e) {}

}

public void update(Graphics g) {

paint(g);

}

public void paint(Graphics g) {

バッファ用のイメージオブジェクトを保持する変数です

バッファ用のイメージオブジェクトをア

プレットのサイズで生成します

アプレットの update メソッドをオーバーライドして、

背景の塗りつぶし処理を省きます。

Page 123: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

123

drawBufferImage();

g.drawImage(buffer, 0, 0, this);

}

private void drawBufferImage() {

Graphics bufferg = buffer.getGraphics();

Dimension d = getSize();

bufferg.setColor(Color.white);

bufferg.fillRect(0, 0, d.width, d.height);

bufferg.setColor(Color.black);

bufferg.fillRect(x, 100, 100, 100);

}

}

■まとめ■

・ダブルバッファリングを用いることで、アニメーション表示時の画面のちらつきを防ぐことができます。

・ダブルバッファリングは、アプレットと同じ大きさの Image オブジェクトを作成し、こちらに描画を行っ

てからアプレットに描画結果を転送することを行います。

練習問題

1. マウスカーソルの動きに合わせて円が動くアプレットを作成してみましょう。

Example11_1.javaとExample11_2.javaを参考にしましょう。

2. 中央に描画された四角形がだんだん大きくなるアニメーション表示を行うアプレットを作成して

みましょう。Example11_6.javaを参考にしましょう。

バッファイメージを描画します

バッファイメージに四角形を描画するメソッドを呼び出します

バッファイメージを白で塗りつ

ぶします

バッファイメージに四角形を描画

します

バッファイメージの Graphicsオブジェク

トを取得します

Page 124: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

124

問題の解答

【1】

(1) コンピュータが理解できるのは機械語であり、人間が作成したプログラムコードをそのまま理解するこ

とはできません。

(3) Javaは大規模で複雑なプログラムを効率的に開発するための仕組みが準備されています。

(5) Javaではコードをコンパイルすると、拡張子が.classの中間コード(クラスファイル)が作成され

ます。

【2】

1. 変数xの宣言がありません。

x = 3.2 – 2.1;

という行の前に

double x;

の記述を追加します。

2.

(1) a += 5 (2) b -= 6 (3) c *= a (4) d /= 3 (5) e %= 2 (6) f++ (7) g--

3.

class Practice2_3 {

public static void main(String args[]) {

int a = Integer.parseInt(args[0]);

int b = Integer.parseInt(args[1]);

int c = a * b;

System.out.println("積は" + c);

}

}

【3】

1. (1) a == b (2) a != b (3) b < c (4) a <= b (5) c >= b

2.

if(a % 2 == 0) {

System.out.println("偶数です");

} else {

System.out.println("奇数です");

}

3.

for文を使用した場合

class Practice3_3_1 {

public static void main(String args[]) {

int sum = 0;

for(int i = 10; i <= 20; i++) {

sum += i;

}

Page 125: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

125

System.out.println("答えは" + sum);

}

}

while文を使用した場合

class Practice3_3_2 {

public static void main(String args[]) {

int sum = 0;

int i = 10;

while(i <= 20) {

sum += i;

i++;

}

System.out.println("答えは" + sum);

}

}

4.

iが1のとき

A

iが2のときは何も出力されない

iが3のとき

B

C

iが4のとき

C

iが5のとき

C

5.

(1) (a == 5) || (a == 8)

(2) (a < b) && (c < b)

(3) ((a > 1) && (a < 10)) || (a != 5)

(4) ((a == b) || (a == c)) && (a != d)

【4】

1. 略

2.

原因:オブジェクトの生成を行っていません。

対策

Rectangle r;

の行の後に次の1行を追加します。

r = new Rectangle();

3.

class Rectangle {

Page 126: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

126

double width; // 幅

double height; // 高さ

double getArea() {

return width * height;

}

}

4.

class Practice4_2 {

public static void main(String args[]) {

Rectangle r; // Rectangleクラスのオブジェクトを格納する変数rを宣言する

r = new Rectangle();

r.width = 3.0; // rの持つ変数widthに3.0を代入する

r.height = 1.5; // rの持つ変数heightに1.5を代入する

System.out.println("長方形の面積は" + r.getArea());

}

}

【5】

1. コンストラクタとはクラスのオブジェクトが作成される時に自動的に実行される、クラスメイト同じ名

前のメソッドです。

2. オーバーロードとは、同じ名前のメソッドを、引数の型や引数の数を変えて複数定義することです。

3.

class Point3D {

double x; // x 座標値

double y; // y 座標値

double z; // z 座標値

// コンストラクタ

Point3D(double x, double y, double z) {

this.x = x;

this.y = y;

this.z = z;

}

}

4. インスタンス変数はオブジェクトごとに保持される変数ですが、静的変数は同じクラスのオブジェクトで

共有される変数です。

5.

class SimpleCalc {

static int getSum(int a, int b) {

int sum = 0;

for(int i = a; i <= b; i++) {

sum += i;

Page 127: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

127

}

return sum;

}

// 新しく追加したメソッド

static double getSquaredValue(double d) {

return d * d;

}

}

【6】

1.

(3) クラスのスーパークラスはただ1つだけです。

(5) オブジェクトが生成されるときは、スーパークラスのコンストラクタが実行されてからサブクラスのコ

ンストラクタが実行されます。

2.

メソッドのオーバーライドとは、スーパークラスで定義されているメソッドと同じ名前(かつ同じ引数)のメ

ソッドをサブクラスでも定義することを言います。

3. (3) (4) (6)

4. 抽象クラスとは、オブジェクトを生成できないクラスのことです。

【7】

1. インターフェイスとはどのようなものか

2.

(2) 1つのクラスが複数のインターフェイスを実装することができます。

(3) インターフェイスを実装するクラスは、インターフェイスに含まれるメソッドを全て定義する必要があ

ります。

3. (1) true: オブジェクトaはクラスAのインスタンスです。

(2) false: オブジェクトaはクラスBのスーパークラスのインスタンスです。

(3) true: オブジェクトbはクラスAのサブクラスのインスタンスです。

(4) false: オブジェクトcはクラスAと関係がありません。

(5) true: オブジェクトcはインターフェイスIを実装しています。

4. 略

5. (1),(4)

((4)のjava.langパッケージはimport文が無くても使用できます)

【8】

1. (2) 例外オブジェクトの型と catch ブロックで受け取るオブジェクトの型が一致した場合だけ catch

ブロック内の処理が実行されます。

2. 略

【9】

1.

Page 128: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

128

import java.io.*;

class Practice9_1 {

public static void main(String args[]) {

try {

FileWriter fw = new FileWriter("c:¥¥java¥¥test.txt");

BufferedWriter bw = new BufferedWriter(fw);

// iの値を0から50まで1増やしながらループします

for(int i = 0; i <= 50; i++) {

if(i % 3 == 0) { // iが3の倍数の場合だけ次の処理を行います

bw.write(i + "¥n"); // iの値をファイルに書き出します

}

}

bw.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

2.

import java.io.*;

class Practice9_2 {

public static void main(String args[]) {

try {

FileReader fr = new FileReader("c:¥¥java¥¥test.txt");

BufferedReader br = new BufferedReader(fr);

int i = 1; // 行番号を記憶するための変数です

String s;

while((s = br.readLine()) != null) {

// 「行番号:行の内容」の形式で出力します

System.out.println(i + ":" + s);

i++; // 行番号を1増やします

}

br.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

実験に使用するファイル名を指定します

実験に使用するファイル名を指定します

Page 129: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

129

3.

import java.io.*;

class Practice9_3 {

public static void main(String args[]) {

try {

FileReader fr = new FileReader("c:¥¥java¥¥data.txt");

BufferedReader br = new BufferedReader(fr);

StreamTokenizer st = new StreamTokenizer(br);

double sum = 0; // 合計値を記憶しておく変数です

while(st.nextToken() != StreamTokenizer.TT_EOF) {

// 読み取った文字が数字だった場合だけ処理します

if(st.ttype == StreamTokenizer.TT_NUMBER) {

sum += st.nval; // sum に読み取った値を加算します

}

}

br.close();

// 合計を出力します

System.out.println("合計は" + sum);

} catch (Exception e) {

System.out.println(e);

}

}

}

【10】

【11】

1.

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

/*

<applet code="Practice11_1" width=300 height=300>

</applet>

*/

public class Practice11_1 extends Applet implements MouseMotionListener {

実験に使用するファイル名を指定します

Page 130: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

130

int x = 150;

int y = 150;

public void init() {

addMouseMotionListener(this);

}

public void paint(Graphics g) {

g.setColor(Color.red);

g.fillOval(x - 10, y - 10, 20, 20);

}

public void mouseMoved(MouseEvent e) {

x = e.getX();

y = e.getY();

repaint();

}

public void mouseDragged(MouseEvent e) { }

}

2.

import java.applet.*;

import java.awt.*;

/*

<applet code="Practice11_2" width=300 height=300>

</applet>

*/

public class Practice11_2 extends Applet implements Runnable {

int size = 0; // 四角形の大きさを表す変数

Thread thread;

public void init() {

thread = new Thread(this);

thread.start();

}

public void run() {

try {

while(true) {

repaint();

Thread.sleep(100);

Page 131: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

131

size += 5; // 四角形の大きさを増やす

if(size > 300) { // アプレットの大きさを超えたらゼロに戻す

size = 0;

}

}

} catch(Exception e) {}

}

public void paint(Graphics g) {

// 四角形を描画する

g.fillRect(150 - size / 2, 150 - size / 2, size, size);

}

}

Page 132: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

132

付録 JDKのインストールと環境設定

JDKをインストールして環境設定を行うために、まずインストーラをインターネットからダウンロードしま

す。次に、ダウンロードしたインストーラを実行し、最後にパスの設定を行います。

■ JDKのダウンロード

Sun Microsystems 社のサイトから JDK をダウンロードします。本書執筆時の最新バージョンは JDK6

Update10です。

次のURLからダウンロードのページへ移動します。

http://java.sun.com/javase/ja/6/download.html

リンクをクリックします

Page 133: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

133

First Customer Ship のページが英文で表示されます。

Windows を使用している場合は Platform に Windows, Language に[Multi-language]を選択しま

す。

[I agree to the ・・・] のチェックボックスにチェックしてライセンス状況に同意し、[Continue]ボ

タンをクリックします。

[Windows Offline Installation]をチェックし、jdk-6u10-windows-i586-p.exeのリンクをク

リックしてダウンロードします。 [保存]を選んでパソコンの任意のフォルダに保存します。

リンクをクリックします

Page 134: プログラミング言語Java - Jun MITANImitani.cs.tsukuba.ac.jp/.../java/JavaBook2008mitani.pdfプログラミング言語Java 学習用テキスト 2008.12.1 PDF 版 初版 三谷

(c) 2008 三谷純

134

■JDKのインストール

ダウンロードしたファイルのアイコンをダブルクリックすると、インストーラが起動します。

インストーラのダイアログに表示される指示に従ってインストールを行ってください。特に設定を変更せず、

全て初期設定のままインストールを進めて問題ありません。

メモ WindowsXPの場合は管理者権限のあるユーザーでインストールする必要があります。

インストールの詳細は以下のURLにも記載されているので、不明な点は参考にしてください。

http://java.sun.com/javase/ja/6/webnotes/install/index.html

■パスの設定

Javaのコンパイラであるjavacとアプレットビューアをコマンドラインから使用するために、インストー

ル先の「C:¥Program Files¥Java¥jdk1.6.0_10¥bin」にパスを設定します。

【WindowsXP】

[スタート]→[コントロールパネル]→[パフォーマンスとメンテナンス]→[システム]を選択し、[システム

のプロパティ]ダイアログの[詳細設定]タブを選択します。

続いて[環境変数]ボタンをクリックし、[システムの環境変数]の[Path]という項目を選択して[編集]ボタ

ンをクリックします。

[システム変数の編集]ダイアログで、[変数値]の欄の末尾に

;C:¥Program Files¥Java¥jdk1.6.0_10¥bin

を追加します。

「保存」を選択します