Fujitsu The Possibilities are Infinite

 

COBOL技術者のためのJava言語入門
1章:変数と定数

[索引]  基本データ型 |  型宣言 |  代入 |  型変換 |  文字列型 |  定数 |  識別子の命名規則 |  コラム 

基本データ型(プリミティブデータタイプ)

Javaではデータを格納する場所を「変数」と呼んでいます。 COBOLのデータ項目に相当するといえるでしょう。 COBOLのデータ項目ではPICTURE文字列を使用して任意の桁数の数字項目や文字項目を定義することができました。 しかしJavaでは長さが決まった以下の8種類の変数しか使えません。 これを基本データ型と言います。

名称 ビット長 内容 値の範囲 デフォルト値
boolean  1 真偽値 trueまたはfalse false
char 16 文字(Unicode) \u0000~\uFFFF(*) \u0000
byte  8 符号付き整数 -128~127 0
short 16 符号付き整数 -32768~32767 0
int 32 符号付き整数 -(2の31乗)~(2の31乗)-1 0
long 64 符号付き整数 -(2の63乗)~(2の63乗)-1 0
float 32 浮動小数点数 単精度浮動小数点数 0.0
double 64 浮動小数点数 倍精度浮動小数点数 0.0

(*)\uXXXXは16進表示

★ この8種の内容と値の範囲はぜひ記憶してください。 整数型はいずれも正の数の値の範囲が負の数より 1 だけ少なくなっています。 これは 0 が正の数側に入るからです。


【確認問題】 1.1

int型のビット長と値の範囲を述べてください。

型宣言

COBOLではデータの定義域(DATA DIVISION)と処理の定義域(PROCEDURE DIVISION)とを区別していました。 Javaでは1つのプログラムの中に、これらを混在させて記述します。 変数を使うには、まず変数の型宣言を行います。 型宣言は次のようにデータ型名の後に変数名を書くことによって行います。 変数の型宣言はそれを使う前ならばプログラム中のどこにあってもかまいません。

        int a;          // int(32ビット整数)型のaと言う名前の変数を宣言

Javaでは文の最後にセミコロン( ; )を付けます。 セミコロンがあれば1行に複数の文を書いてもかまいません。 本記事ではスペースの節約のために1行に複数の文を書くことがありますが、実際の業務ではあまり使わない方が良いでしょう。 またJavaではスラッシュ( / )を2つ連続して書くと、それ以降がコメント文になります。

複数データの型宣言

複数の変数をまとめて型宣言することもできます。 実際のプログラムではこの書き方もあまりしない方がベターです。

        double b,c;     // double(倍精度浮動小数点数)型の変数b,cを宣言

【確認問題】 1.2

16ビットの整数型の変数 i を宣言してください。

代入

変数に値を代入するときは次のように等号( = )を使います。 代入のやり方はこれだけで、MOVE文はありません。

        a = 10;
        b = 12.3;
        c = b + 4.5;

初期化

型宣言と同時に値を設定することができます。 COBOLならVALUE句を使うところです。

        int a = 10;
        double b = 12.3;

値の設定の必要性

Javaでは値が設定されていない変数を参照しようとするとエラーになります。 このエラーはコンパイルの段階で指摘してくれるので大変便利です。 ただし後述のように変数の宣言場所によっては、デフォルト値が設定されることがあり、この場合にはエラーにはなりません。


【確認問題】 1.3

倍精度浮動小数点数型の変数 d を宣言して 3.14 で初期化してください。

型変換

変数の演算は同じデータ型どうしで行うのが望ましいのですが、実用上はそれでは済まないときがあります。 そのために以下のような型変換機能が用意されています。

  • 演算時の変換(演算時に互いの型を合わせる)
    1. 表現の範囲が大きな方の型に合わせる。 大小関係は以下の通り。
      double > float > long > int
      32ビットのfloatの方が64ビットのlongより大きいことに注意。
    2. intより小さいbyte、char、shortはintに変換される。
  • 代入時の変換(右辺の型を左辺の型に変換する)
    1. 左辺の型の表現範囲が右辺の型より大きい場合はそのまま代入される(拡張変換)。
      int → float などの代入ではエラーにはならないが、有効数字は落ちることがある。
    2. 逆の場合はコンパイルエラーとなる。 ただし型変換を明示的に指定すれば、はみ出した部分が切り捨てられて代入される(縮小変換)。 shortとchar間およびbyteとchar間はいずれも縮小変換。 (符号情報の欠落などがあるため)

キャスト ★

上記 4. で述べた、明示的な型変換をキャストといいます。 キャストは変数名の前に、変換先の型名を括弧でくくることで行います。 キャストの例を示します。

        int id = 65539;
        short sd;
     × sd = id;        // 縮小変換(32→16ビット)なのでコンパイルエラーとなる
        sd = (short)id  // キャストしたのでOK。上位が切り捨てられ、sdは3になる

文の前に × がついているのはエラーになることを示しています。

※ このように、Javaは型変換に大変「うるさい」言語です。 厳しくチェックすることで、うっかりミスによるバグを防止しようとの意図があります。 C → C++ → Java と新しい言語が作られるたびに、規則は厳格化してきました。

char型の値

charは文字ですが、算術演算を行うときは符号無し16ビット型として扱われます。

        char cd = (char)65534;
        int id =  cd;   // idは65534になる
        short sd = (short)cd;   // 先頭ビットを符号とみなしsdは-2になる

boolean型の値 ★

boolean型の値はtrueかfalseのいずれかです。 boolean型は他のどのデータ型へも型変換できません。 逆に他のどの基本データ型からも型変換できません。


【確認問題】 1.4

次の式でコンパイルエラーになるものを全て挙げてください。

  01:   short s = 1000;
  02:   boolean x = (boolean)s;
  03:   byte b = (byte)s;
  04:   char c = s;
  05:   int i = s;
  06:   float f = s;
  07:   s = s + s;

文字列型 ★

文字列を格納する変数はStringと言う型にします。 Stringを使うと文字列を簡単に操作することができます。 文字列を + で結ぶと文字列を結合できます。 文字列と数値を + で結ぶと数値を文字に変換してから結合します。 以下の例を見てください。

        String ss = "ABC";      // String(文字列)型の変数ssを宣言し値ABCを代入
        ss = ss + "DEF";        // 文字列結合がおこりssは"ABCDEF"になる
     × ss = 111;               // 数値を文字列に代入するのでコンパイルエラー
        ss = "" + 111;          // 文字列に変換してから代入するのでssは"111"
        ss = 111 + 222 + "";    // 整数値の加算後、文字列結合するのでssは"333"
        ss = "" + 111 + 222;    // 文字列結合がおこるのでssは"111222"
        ss.length();            // 文字列の長さをint型で返す

Javaでは文字はUnicodeで記述されます。 UnicodeはJIS漢字コードやそれを変形したShiftJIS、EUCなどとは全く異なった文字コード体系ですので規則的な変換はできません。


【確認問題】 1.5

文字列型の変数 str を宣言して値 "XYZ" で初期化してください。


【確認問題】 1.6

int 型変数 r に値 10 が格納されています。 文字列 res を宣言し、r を使って res に "結果は10です" が入るようにしてください。

定数

定数は値の決まった数や文字のことでリテラルとも呼ばれます。 定数には整数、浮動小数点数、文字、文字列などがあります。 整数値は、10進数だけでなく、8進数や16進数で表現することもできます。

        0123;   // 0で始まると8進数。10進表示では64+2*8+3で83になる
        0x1234; // 0xで始まると16進数。10進表示では4660になる

定数の型(整数)

定数にも変数と同じように型があります。 単に整数値を書くとint型とみなされます。 int型ではなくlong型であることを明示したいときには、数値の後ろに L または l(小文字のL)を付けます。 以下の1行目は右辺の数字がint型と見なされ、代入前の時点でエラーになります。 2行目のように数字の後ろに L を付ければOKです。

     × long ld = 12345678900;  // 数値がintの範囲を越えるのでコンパイルエラー
        long ld = 12345678900L; // long型であることを明示したのでOK

浮動小数点数

小数点付きの数値はデフォルトでdoubleとみなされます。 double型ではなくfloat型であることを明示したいときには、数値の後ろに F または f を付けます。 浮動小数点数は指数形式であらわすこともできます。

     × float fd = 12.34;       // 数値はdouble型なのでコンパイルエラー
        float fd = 12.34f;      // float型であることを明示すればOK
        double dd = 1.2e-3;     // 指数形式で指定。ddは0.0012になる

文字定数と文字列定数

文字をシングルクォート( ' )で囲むと文字定数になります。 一方ダブルクォート( " )で囲むと文字列定数になります。 前者は1文字だけ、後者は複数文字を扱うので違いに注意してください。

        char cd1 = 'A'  // 半角文字のUnicodeはJIS7ビットコードと同じ
        char cd2 = '漢' // 漢字1字も文字定数
     × char cd3 = 'AB' // これは文字列なのでコンパイルエラー
     × char cd4 = "A"  // 文字列を文字に代入するのでコンパイルエラー

エスケープ文字(\)

改行やタブコードなどは次のように \ と特定の文字を組み合わせて表現します。

        String s1 = "ABC\n";    // ABC(改行)を示す。nは new line の略
        String s2 = "A\tB";     // A(タブコード)Bを示す
        char c1 = '\'';         // シングルクォート(')を示す
        char c2 = '\"';         // ダブルクォート(")を示す
        char c3 = '\\';         // \自身を示す

【確認問題】 1.7

次の式でコンパイルエラーになるものを全て挙げてください。

  01:   byte b = (byte)513;
  02:   int i = (int)12.34;
  03:   float f = 1.2e2;
  04:   char c = '\\';
  05:   short s = (short)0128;

識別子の命名規則 ★

変数の名前の付け方には次のような規則があります。 文字の長さの制限はありません。 これらの規則は変数名だけでなく、後述のメソッド名やクラス名などの命名規則としても適用されます。 これらを他と識別する名前であるとして識別子と呼びます。

  1. 使える文字は英字(大文字、小文字)、数字、$、下線( _ )。 数字は先頭には使えない
  2. 予約語(キーワード)は使えない(予約語リストを後述)
  3. 英字の大文字と小文字は区別される(Dataとdataは全く別の変数になる)
  4. 漢字や全角かななどもUnicodeなので使える(実際にはあまり使われない)

※ COBOLではハイフンが使えますが、Javaではダメです。 かわりに下線が使えます。

慣用規則

以上の他に慣用として次の規則も広く使われます。 これらは言語仕様ではないので、従わなくてもエラーにはなりません。

  1. 基本的に英小文字を使用する
  2. 変数名とメソッド名は英小文字で始める
  3. クラス名は英大文字で始める
  4. 2単語目の先頭は英大文字とする(例: myData(変数名)、MyClass(クラス名))
  5. 定数値を入れるときは全部を大文字にすることが多い(例: MAXVALUE)

予約語リスト

Javaの予約語を示します。 本記事を最後まで読まれると、以下の殆どの単語の意味と使い方がわかるはずです。 これらを覚えていくことが、Javaの学習といえます。 以下で * 付き以外の語はそのうち本記事で、出てきます。

  • 基本データ型とその値(9語)
    byte, char, short, int, long, float, double, boolean, void
  • クラス関連(10語)
    class, interface, extends, implements, this, super, new, instanceof, import, package
  • 修飾子(11語)
    public, protected, private, final, static, abstract, native*, synchronized, volatile*, transient*, strictfp*
  • 制御構造関連(11語)
    if, else, for, while, do, switch, case, default, break, continue, return
  • 例外処理関連(5語)
    try, catch, finally, throw, throws
  • 使用されないが予約されている(2語)
    const*, goto*
  • 予約語ではないがリテラルとして定義されていて識別子として使えない(3語)
    true, false, null

【確認問題】 1.8

以下の中でJavaの識別子として正しくないものを全て挙げてください。

        data#3, file, $23, byte, Java, Int, my-class, String, _num

☆☆☆コラム☆☆☆ ---- JavaとCOBOLの機能対比(1)

  1. COPY句(COPY文)

    COPY句はあらかじめ作成しておいたソースファイルを、コンパイル時に、自分のソースにコピーして利用することができる、いわばソースの再利用の命令です。 何度も使うレコード定義や処理パターンのソースを作成しておけばプログラムの生産性や信頼性を高めることができます。

    残念ながらJavaにはこのようなソースレベルでの再利用機能はありません。 Javaで類似した機能を探すとすれば、それはクラスということになるでしょう。 例えば次のようなレコードを定義していたとします。

            --------SHAIN.CBLファイル---------
             03 SHIMEI      PIC X(10).
             03 SHAIN-CODE  PIC 9(8).
             03 SYOZOKU     PIC X(20).
            ----------------------------------

    Javaでは、以下のようなクラスに対応します。

            class Shain {
              String simei;
              int shainCode;
              String syozoku;
            }

    形式的にはこれだけですが、使い方はかなり違います。 すなわちCOBOLでは、上記のファイルをCOPY句で指定するだけでメモリ領域が確保され、各レコードはそこを使って入出力や処理を実行します。 しかしJavaでは、使うたびにnew命令でメモリ上にオブジェクトを生成し処理する必要があります。

    またJavaで作るのでしたら、単にデータを定義するだけではなく、そのデータを読み書きするメソッドも同じクラス内に書いた方が良いでしょう。 さらに上記のデータにprivate属性をつけ、読み書きはメソッドに任せるようにすれば、よりオブジェクト指向の考えに沿ったプログラムになります。

  2. 集団項目

    COBOLには集団項目と言う考え方があります。 個々のデータ項目を定義した後、それらをひとまとめにして名前をつけて管理するという考え方です。 まとめたものをさらにまとめて名付けるといったように、集団項目は階層的に定義できます。

    Javaには直接的に対応する機能はありません。 あえていえば、これも関連するデータ群をクラスとして定義することに相当するでしょう。 例えば、前述のSHAINが集団項目として定義されていれば、Shainクラスを定義することで、まとめて扱えるようにしたと言えます。 クラスの要素としてクラスを取り入れることもできますので、階層的な集団項目にも対応できます。

    しかし集団項目をすべてクラスとして定義してしまうのは、やりすぎかと思います。 集団としてまとめて扱う意味のあるものに限るべきでしょう。 またJavaではよく使われるデータの集まりとして、Date、Calendar、Dimension(幅,高さ)、Point(x座標,y座標) などのコアライブラリーが用意されているので、これらを活用するのもよいでしょう。