C言語では、ローカル変数をブロックの先頭で、実行文を始まる前に、まとめて宣言する必要がありました。
C言語では、auto変数の宣言を{ } のブロック内先頭でまとめて宣言しました。
つまり、実行文の後で、宣言文を使うとコンパイルエラーでした。
文の参考⇒(確認後はブラウザの戻る操作で戻ってください)
そのような制約がなくなり、使う前であれば、実行文を記述した後で宣言しても構いません。
しかし、初期化しない変数を使うと警告(warning)でなくエラーになります。←(C言語ではwarningでした)
以下にエラーとなるプログラム一部と、コンパイルエラーの表示を示します。
int c; c = c + 1;
ソースファイル名:エラー箇所でソース行番号: 変数 c は初期化されていない可能性があります。 c = c + 1; ^
以下のように初期化すると、エラーはなくなります。なおJavaでは、行単位のコメントで//の表現を使い、記述位置よりその行終端までがコメントになります。 なお、複数行も含めたある範囲をコメントにするには、C言語と同じ/* */を使います。
int c=0; //0が記憶される変数を作る c = c + 1;
以下のように、cへの代入演算子を使ってもエラーはでません。
int c; //C言語と同じで、何が記憶されるか分からない変数になります。 c = 0; c = c + 1;
しかし、その判断は論理的なミスに対して考慮されていません。(今後コンパイラの性能が上がれば考慮できるかも?) よって、上記でエラーにならないのに、下のプログラムでは『変数 c は初期化されていない可能性があります』のエラーが出ます。
int c; //C言語と同じで、何が記憶されるか分からない変数になります。 boolean b=true;// 論理値のtrueかfalseを記憶変数で、trueで初期化 if (b){ c = 0; } c = c + 1;
上記では、bに成立の意味のtrueが記憶されているのでifで必ず成立して、必ずc = 0が実行されます。
よってc + 1の実行時はcに0が記憶されることは明らかなのでコンパイルエラーにしなくてもよさそうです。
しかしエラーなので、そこまでコンパイラが賢く作られていないということです。
なおJavaのifやwhile for など、判定式を書く部分に、演算結果が(true 又は false)の値になる表現を書かなければなりません。
これは、boolean(ブーリアン)型になります。
C言語では成立が『0以外の値』でしたが、Javaではtrueが成立の意味の定数です。
逆にfalseが不成立の意味の定数です。
Javaでは結果がtrueやfalseのboolean型にならない式をifなど条件式に使うとコンパイルエラーです。
なお、Javaではforの繰り返し前の初期設定部で、変数宣言が可能です。その変数スコープは繰り返し対象範囲内だけとなります。 以下に例を示します。 が通用範囲です。
int sum=0; //1+2+3+4を求める
for (int n = 1; n <= 4; n++){
sum += n;
}
//ここで、sumの変数は使えるが、変数 n は、存在しないので使うとコンパイルエラーです。
またC言語と異なり、次のように{ のブロック内部で、同じ名前の変数を使うことは許されていません。
{ int n = 1; { int n = 5;// C言語では可能ですがJavaでは許されません。この位置にコンパイルエラーの指摘がでます } // C言語では、この位置で、1が記憶される変数nが使える。 }
すでに〜で定義されています。のエラーになります。つまり、あいまいに見える変数を作れなくしているのです。
(C++と発展した言語では、C言語仕様を引きずるので可能です)
その他のauto変数(メソッドの中で宣言する変数)のスコープは、C言語と同じように考えてください。
C言語の型の参考⇒(確認後はブラウザの戻る操作で戻ってください)
C言語に似ている型の体系ですが、intやshortやlong型のあいまいな意味をなくしています。次がJavaの型の種類で、変数宣言で利用します。
大分類 | 型:宣言時に使うキーワード | 記憶範囲 |
---|---|---|
論理型 | boolean | 関係演算のtrueかfalse |
整数型 | byte | 1byteの-128〜127 |
char | 文字16bit(\u0000〜\uffff) | |
short | 16bit整数 | |
int | 32bit整数 | |
long | 64bit整数 | |
実数 | float | 単精度浮動点少数(32bit) |
double | 倍精度浮動点少数(64bit) | |
参照型 | Stringクラス | 文字列 |
StringBufferクラス | 変更を目的にした文字列 | |
その他のクラス | 目的に応じてたくさんのクラスがある | |
配列型 | 上記の全てや、配列を、配列の要素にできます。 |
新しい型で、成立を意味する定数trueか、
不成立を意味するfalseのどちらかだけを記憶できるboolean(ブーリアンと呼びます)の型があります。
charは、2byteの文字を記憶する型です。
C言語のchar型はbyte型に対応します。
論理型、整数型、実数型が基本型となります。
そしてオブジェクトを参照する参照型があり、この2つに分類する考え方があります。
基本型はif(a == b)〜で記憶内容が等しいか判定ができますが、参照型はC言語のポインタと同じように、
データの中身をチェックするのではなく、『同じ記憶域を指し示すか?』 の判定です。
"123"や"abc"の表現はポインタではなく、
文字列というString型を使います。
Scannerクラスのように既存のクラス以外に、プログラマが作るクラスを含めると無限の型があると言えます。
クラスとは、情報や命令の入れ物で、それらをまとめた設計書と考えるとよいでしょう。
既存のクラスが始めからたくさん用意されており、それらクラスの情報や機能を利用してプログラミングします。
クラスの情報を利用する場合、クラス名の型の変数を用意し、
オブジェクトをnew 演算子で生成して=の代入演算子で管理させて(参照させて)使う形態になります。
C言語では、int型変数へdouble型データの代入が許されていました。
しかし、これで情報を失うプログラムミスになりがちです。
(警告(warning)を出しましたが、コンパイルはできてきます。)
ミスでなく意図的に行う場合はキャスト演算を使いました。
C言語キャスト演算の参考⇒(確認後はブラウザの戻る操作で戻ってください)
さて、Java言語では情報を失うプログラムミスをなるべく無くすために、
型のチェックは厳しくしています。
それは、情報を失う可能性の代入はキャスト演算が必要で、それを行わない場合は
warningでなくコンパイルエラーにしています。以下に例とコンパイラメッセージを示します。
int i; double d = 1.23; i = d; // (int) d のキャスト演算子を使わないとエラーです。
ソースファイル名:エラー箇所でソース行番号: 精度が落ちている可能性 検出値 : double 期待値 : int i = d; ^