15 「ご注文はなんですか?」~入力ライブラリの利用~

【第15回】「ご注文はなんですか?」~入力ライブラリの利用~

今回は、ユーザーからの入力を受ける方法について説明します。

前提: 第4回の講座を理解し、プログラムの3大要素について抑えている。

今回は、「入力」についての話です。
ユーザーにキーボードから文字列を入力してもらう方法を学びましょう。

1.まずは入力してみよう!

今回はどちらかというと覚えることの方が多いので、まずプログラムを書いてみましょう。(リスト1)

リスト1 – StreamTest.java

import java.io.*;

public class StreamTest
{
    public static void main (String[] args) throws IOException         //(4)
    {
        InputStreamReader is = new InputStreamReader(System.in);       //(1)
        BufferedReader br = new BufferedReader(is);                    //(2)

        System.out.println("何か入力してください.");

        String str = br.readLine();                                    //(3)

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

リスト1をコンパイルして実行してみます。
実行すると次のように表示されるので、好きな文字列を入力してみましょう。

C:\work>java StreamTest
何か入力してください.

ここでは、「Hello, world.」と入力してみます。

C:\work>java StreamTest
何か入力してください.
Hellow, world.
Hellow, world.が入力されました.

C:\work>

入力した文字列が表示されましたね。リスト1は次のような処理を行う最も簡単なプログラムです。

1. ユーザから文字列を入力し、

2. 入力された文字列をそのまま表示する

リスト1をもう少し詳しく見ていくことにしましょう。

(1)と(2)の部分は、ユーザから文字列を入力してもらうための準備です。
まずは「おまじない」だと思っておきましょう。

(3)の部分が、実際に文字列を入力する部分です。
(2)で作った BufferedReader というクラスのインスタンス br の
readLine というメソッドを呼び出しています (クラスやインスタンスといった言葉がわからない人は、
Java講座 第10回第11回を読み直してくださいね)。
BufferedReader は、文字列を入力するための標準クラス
(Javaであらかじめ用意されているクラス)と思ってください。

最後に(4)の部分についてですが、(3)の readLine メソッドで IOException という例外が
発生する可能性があるため、そのことをJavaに知らせるためのものです。
ここも、まずはおまじないと思っておけば良いです。
(例外については Java講座 第14回を参照してください)

(1)~(4)を正しく記述しておけば、とりあえずユーザから何かを入力してもらい、
それを String に格納することができます。

2.入力の仕組みを知る

さて、ひとまず入力ができるようになったところで、Javaの入力の仕組みをもう少し勉強しましょう。
先ほどあまり説明しなかった、リスト1の(1)、(2)のところにその秘密が隠されています。

(1)では InputStreamReader というクラスを、(2)では、 BufferedReader というクラスを
それぞれ生成しています。これらのクラスの役割を説明しましょう。

まず(1)の InputStreamReader ですが、大雑把にいうと
「指定された所から1文字分のデータを読みとる」という処理をしています。
「指定された所」に相当するのが、System.inです。
System.inは初めて見るかと思いますが、今まで画面に文字を表示するのに使ってきた
System.outの反対で、画面(正確には「標準入力」といいますが)からデータを入力するために
使用するオブジェクトです。

ここで、JavaのAPIリファレンスで InputStreamReader を調べてみましょう。
(APIリファレンスの調べ方については第8回で説明していますので、
忘れてしまった方はそちらを読み返してみてくださいね)

InputStreamReader には read というメソッドがありますが、
このメソッドの戻り値は「int」です。つまり、InputStreamReaderは
「1文字分のデータを読み込んで、その文字コードを返すことしかできない」のです。
文字コード
とは、コンピュータの中で使用されている文字を表す数値のことです。

試しに、InputStreamReader を使用したプログラムを作成してみましょう。(リスト2)

リスト2 – InputTest.java

import java.io.*;

public class InputTest
{
    public static void main (String[] args) throws IOException
    {
        InputStreamReader is = new InputStreamReader(System.in);

        System.out.println("何か入力してください.");

        int charCode = is.read();

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

コンパイルして実行すると、先ほどと同じように入力を求められます。

C:\work>java InputTest
何か入力してください.

今度は、「a」と入力してリターンキーを押してみます。

C:\work>java InputTest
何か入力してください.
a
97が入力されました.

C:\work>

ここで表示された「97」が、入力された「a」を表す文字コードなのです。
このままでは、ちょっと使いづらいですよね。
そこで登場するのがリスト1の(2)、BufferedReader なのです。

BufferedReader は、InputStreamReaderを引数として渡すことで、
効率よく文字列を入力することができます。
(2)で BufferedReader を new する際に、引数として(1)で生成した
InputStreamReader のインスタンス is を渡していますね。
こうすることで、BufferedReader を経由して InputStreamReader を使用することになるのです。

ちなみに、このような使い方をすることを、「ラップする」といいます。
InputStreamReader を BufferedReader でくるむようにして使うことから
このように言われているのです。

最終的には、BufferedReader の readLine メソッドを使うと、
コンストラクタの引数で指定された InputStreamReader を使用して
1行単位の文字列を入力できるようになっているのです。

3.クラスの役割分担

さて、これでキーボードからの入力を行う方法がわかったかと思いますが、
皆さんの中には次のような素朴な疑問を持っている方が多いのではないでしょうか?

「なんでこんなに面倒くさいの??」

出力するときは、System.out.println を呼び出すだけで良かったのに、
入力の時は色々と準備しておかなければならないことがあって、その意味もわかりにくいですよね。

また、今回は紹介していませんが、Java には InputStreamReader や BufferedReader の他にも
入出力に関わるクラスがたくさんあります(これらは全て java.io パッケージにまとめられています)。

これだけたくさんのクラスがあるのには、次のような理由があります。

・各クラスの機能を単純化して、それぞれの役割を持たせる。
・単純化されたクラスを組み合わせて利用することで、全体として様々な事をできるようにする。

例えば、今回の InputStreamReader には「1文字入力する」といった単純な機能しか持っていません。
また、BufferedReader は、「どのように入力するか」といった部分の機能は持たずに、
InputStreamReaderなどのクラスを利用して1行単位の入力を可能にする、といった
「使いやすさを向上する部分」の役割を担当しているのです。

興味のある人は、APIリファレンスの java.io パッケージの部分を調べてみてください。
もっと色々なクラスが紹介されていますよ。

なんとなくわかっていただけたでしょうか?

最後の部分はオブジェクト指向的な考え方なので、ちょっと難しいかもしれませんが、
頭の片隅にでも入れておいてください。

それでは、今回学んだことをまとめて今回の講義は終わりとしましょう。

~ まとめ ~

1. Javaでキーボードから文字列を入力する方法がわかった
2. InputStreamReader と BufferedReader の役割がわかった
3. java.io パッケージは様々な役割のクラスを組み合わせて利用する

それでは、また次回にお会いしましょう。

→ 次へ(第16回:勝手に変えられたくない...メンバへのアクセス制限)