配列
配列とは同じ型のデータを複数個まとめて番号を付けたものです。 配列はCOBOLで言えばOCCURS句に相当するといえるでしょう。
配列を使うには次のステップが必要です。 配列の要素数は生成時に決める必要があり、途中で増やすことはできません。
配列の添字はCOBOLとは異なり 0 から始まります(0-オリジン)。
配列名を宣言する。
int[] a; // int型の配列aを宣言
配列の要素数を指定して、配列を格納するメモリ領域を確保する。
newはメモリ領域を確保する命令です。
a = new int[5]; // int型の要素を5個確保
各要素に値を設定する。各要素は添字を使って指定する。
a[0] = 10; // 添字は0から始める
a[1] = a[0]; // このようにするとa[1]にa[0]の値が複写される
範囲外のアクセス ★
以下のように、上記 2.
で確保した範囲を越えてアクセスすると、実行時にArrayIndexOutOfBoundsExceptionという例外が発行されます。
× a[5] = 20; // これはエラー。aの要素は0から4までの5個なので
※ このエラーはコンパイル時ではなく、実行時に検出されます。
添字の値は一般に実行してみないとわからないので、コンパイル時には評価しないからです。
まとめた記述
上述の 1. と 2. とをまとめて以下の 01: のように一度で書くこともできます。 また 1.~3. をまとめて 02:
または 03: のように書くこともできます。
01: int[] a = new int[5];
02: int[] a = new int[] { 10, 20, 30, 40, 50 };
03: int[] a = { 10, 20, 30, 40, 50 };
別の流儀
配列の記述の仕方には int a[ ] のように変数名側に角括弧を付ける流儀もあります。
このやり方で上の例を書くと以下のようになります。 C言語などに慣れた人はこの流儀で書くことが多いようです。
この場合でも単独でnewする時は 06: のように変数側には [ ] は付けないので注意してください。 07:
のように書くとコンパイルエラーになります。
04: int a[];
05: int a[] = new int[5];
06: a = new int[5];
07:× a[] = new int[5]; // これはコンパイルエラー
参照型 ★
基本データ型では変数域には値そのものが入りましたが、配列の場合は、配列の実体のデータではなく、格納域のアドレスが入ります。
したがって、以下のように配列 a を別の配列 b に代入すると、格納域へのアドレスが複写され、b も a と同じ実体である {10,
20, 30} を指すことになります。 すなわち a[0]=15 とすると b[0] も 15 になります。
配列の値をそっくり別の領域に移したいときには、1つずつとりだしてコピーする必要があります。
int[] a = {10, 20, 30};
int[] b = {40, 50};
b = a; // bには{10,20,30}へのアドレスが代入される
a[0] = 15; // {10,20,30}が{15,20,30}になる
このように変数域に(データではなく)アドレスが入っている変数の型を、参照型と言います。
Javaでは基本データ型以外の変数はすべて参照型です。 参照型のデータはnewで領域を確保する必要があります。
Java学習の中心テーマである「クラス」も参照型です。
※ Stringも変数域にアドレスが入っているので実は参照型です。
しかしStringは良く使うので、特例としてnewなしで生成できるようになっています。 実際、String str = new
String("abc"); のように書くこともできます。
配列の要素数
配列 a の要素数は次のようにして取得できます。
a.length;
多次元配列
上述の説明は1次元の配列でしたが、2次元以上の配列も宣言できます。 以下に2次元配列の使い方の例を示します。
int[][] a = new int[3][4];
a[0][0] = 100;
a[0][1] = 200;
演算子
Javaには多くの演算子があります。 ここでは、実務で比較的よく使われる主要な演算子について説明します。
変数を演算子で結びつけたものを式と言います。 式の中では丸括弧 ( ) で演算の順序を変更することができます。
算術演算
算術演算は数値を計算するものです。 Javaでは以下の算術演算が可能です。 整数除算を行うと余りは切り捨てられます。 整数を 0
で割るとArithmeticException例外が発生します。
その他加減算より乗除算が優先して行われるなどの規則は一般の数式と同様です。
+ (加算)、- (減算)、* (乗算)、/ (除算)、% (剰余)
※ 以下に演算の例を示します。 演算の指示はCOBOLのCOMPUTE命令と同じです。
ただしCOMPUTEとは書かずに数式のみを書きます。 またADDやSUBTRACTと言った命令はありません。
c = a * b;
d = (e - f) / (e + f);
比較演算
比較演算は主にif文の条件の中で使われます。 「等しい」は == で表し、「等しくない」は != で表現します。
これらはC言語に由来するものです。 比較演算の結果はboolean型になります。
< (小さい)、> (大きい)、<= (小さいか等しい)、>= (大きいか等しい)
== (等しい)、!= (等しくない)
論理演算 ★
論理積と論理和には以下に示すように2種類あります。 && と ||
は左から右に評価し、かつ条件が整えばそこで判定を中止することが保証されています。
これを活用すれば処理の効率を向上させることができます。
& および && (論理積)、| および || (論理和)、^ (排他的論理和)、! (否定)
ビット演算
ビット列を扱う演算ができます。 上記の & | ^ もビット列演算に使うことができます。
<< (左シフト)、>> (符号付き右シフト)、>>> (符号無し右シフト)、~ (反転)
例: a=0xF6D3 のとき、a<<1 は 0xEDA6、a>>3 は
0xFEDA、a>>>2 は 0x3DB4
インクリメント演算/デクリメント演算
Javaでは入力を少しでも減らそうとして以下のような、特有の演算が用意されています。
最初は違和感があるかも知れませんが、使い慣れるとなかなか便利です。
++a (前置型)、a++ (後置型):いずれも a = a + 1 のこと
--b (前置型)、b-- (後置型):いずれも b = b - 1 のこと
★ 前置型では +1 されてから値が式に取り込まれ、後置型では値が式に取り込まれてから +1 されます。 例えば a=++b;
と書くと b を +1 してから b を a に代入しますが、a=b++; と書くと b を a に代入した後で b を +1
します。
代入演算
以下もJava特有の演算です。 これらはいずれもC言語の流れをくむものです。
a += b : a = a + b を表す
a -= b : a = a - b を表す
a *= b : a = a * b を表す
a /= b : a = a / b を表す
a %= b : a = a % b を表す
条件演算
以下のように記述します。 a の真偽を評価し真なら b を、偽なら c を採用します。
a ? b : c;
例: b=(a>0)?10:20; a が正なら b に 10 を代入し、a が正でないなら b に 20
を代入します。
2種類の等価演算 ★
String型などの参照型(変数域にデータ格納先アドレスが入っている型)のデータを比較するときは、次の2種類のやり方があります。
以下では (1) が真なら、当然 (2) も真です。
(1) a == b アドレスの値を比較
(2) a.equals(b) アドレスが指している実体を比較
文字列などの比較は、普通はアドレスそのものではなく、文字列として同じか否かを比較したいので (2) の方式を使います。
☆☆☆コラム☆☆☆ ---- JavaとCOBOLの機能対比(2)
再定義(REDEFINES)
COBOLにはREDEFINESという機能があります。 一度定義した項目を別の目的で使うことができる便利な機能です。
例えば以下のように使います。 一度定義したものを細分化して利用するわけです。
03 ID-CODE PIC X(8) VALUE "PDG00072".
03 CODE2 REDEFINES ID-CODE.
05 CODE-X PIC X(3).
05 CODE-S PIX 9(5).
また以下のようにバラバラに定義したものをまとめ直すこともできます。
03 年月日.
05 年 PIC 9(02).
05 月 PIC 9(02).
05 日 PIC 9(02).
03 日付 REDEFINES 年月日 PIC 9(06).
残念ながら、Javaにはこのような1つのデータを複数の立場から扱うような機能はありません。
文字列の分割(substringメソッド)や連結(+
演算子を初め、append、insertメソッドなど多数)を使ってプログラマーがその場に応じて工夫する必要があります。
ただし後者の例のように汎用的なものは、DateやCalendarクラスが用意されています。
その他の項目
1)固定小数点演算
小数を扱う演算では、COBOLには10進の固定小数点演算がありますが、Javaは言語としては、2進の浮動小数点演算しかありません。
したがって、COBOLのプログラムをJavaに移植する時は精度が異なるので注意が必要です。
固定小数点演算はjava.mathパッケージにあるBigDecimalクラスを使用して10進演算を行うことで対処可能です。
2)クロスリスト
COBOLのコンパイラーでは、変数が使われている状況がわかるクロスリファレンスリストが表示されますが、Javaのコンパイラーでは表示しません。
Javaでは公開するpublic変数は誰に使われても良い覚悟で作る、という考え方からクロスリストを出す発想はなかったのでしょう。
J仕様書工房という市販の製品を使うと、変数やメソッドの使用状況をリストアップすることができます。
J仕様書工房はクロスリスト以外にも様々な情報を得ることができます。
3)データベースアクセス
COBOLではRDBへのアクセスは埋め込み型SQL文を使います。 これは仕様が標準化されているので、ソースの互換性が確保できます。
一方JavaではJDBCというSUNが定めたインターフェースでデータベースにアクセスします。
JDBCではSQL文はプログラムではなく、単なる文字列としてJDBC経由でデータベースシステムに渡されます。
この方法は実行上はあまり問題はないのですが、オブジェクト指向の考え方となじまないため、インピーダンスミスマッチの問題として多くの議論をよんでいます。