変数・定数 Java 基本

modified at:05 July 2015

リテラル

Javaにおけるリテラルとは「10」や「”Hello, Java World!”」のような値や、その表記のことをいいます。

例えば、ダブルクォーテーションマーク( “ )で囲まれたものは、たとえ数字でも文字列になります。例えばプログラムで「"10" + "20"」を実行させた結果は「"1020"」となり「30」になりません。「’“あ” + “か”‘」の結果が「’“あか”‘」になるのと同じです(計算をしてもらうにはダブルクォーテーションマークで囲まず「10 + 20」と記述すればよい)。つまり見た目には同じ「10」と見えていても、コンピューターにとっては、計算できる数値の「10」と文字列の「10」の扱いが異なるので書き方で区別する必要があるのです。そのような区別を「リテラル」といい、区別するためのルール(表記の仕方)があるのです。

整数リテラル

整数にはたくさんの表し方があります。10進数、8進数、16進数の表現の他、Java7からは2進数を表現することができます。それらを区別する表記法を整理してみました。

進数 説明
10進数 255 0から9までの10個の数字を使用して数を表現します。
2進数 0b101 0と1の2個の数字を使用して数を表現します。先頭に0b(ゼロ、ビー)を入れると2進数と判断されます(bは大文字・小文字可)。
8進数 0377 0から7までの8個の数字を使用して数を表現します。先頭に0(ゼロ)を入れると8進数と判断されます。
16進数 0xff 0から9までの数字とAからFもしくはaからfまでのアルファベットを使用して数を表現します。先頭に0x(ゼロ、エックス)を入れると16進数と判断されます(xは大文字・小文字可)。
次の数字を処理系に与えた場合、十進数のいくつのことだと処理系は判断するでしょう。
  • 10
  • 010
  • 0b10
  • 0x10

浮動小数点数リテラル

小数部をもつ数値であり、10進数、指数を表現することができます。

表記 説明
10進数 2.345 小数をそのまま記述します。
指数 2.4e-3 2.4×10の-3乗(「0.0024」)のことで、指数を表すeを使います(大文字可)。

※Java7では、数値リテラルの途中でアンダーバーを入れられるようになりました(「int n = 123_456;」)。

文字リテラル

1つの文字を表すためのもので、シングルクォーテーション( ‘ )で囲みます。アルファベットはもとより、日本語等も1文字を表します。また、印刷できないような文字、例えば、改行文字やタブ等も表現できます。これらは「(バックスラッシュ)」を利用し、「エスケープシーケンス」といわれています。Windowsではこの「(バックスラッシュ)」が「¥マーク」と表示されます。どちらも同じものだと考えて下さい。以下がエスケープシーケンスの一覧です。

エスケープシーケンス 意味
\b バックスペース
\t 水平タブ
\n 改行
\r 復帰
\f 改ページ
\' シングルクオーテーション
\" ダブルクオーテーション
\ \文字
\ooo 8進数の文字コードが表す文字
\uhhhh 16進数の文字コードが表す文字

したがって、「’A’」や「’星’」や「’\n’」等が、文字リテラルです。また、Unicodeや十進数でも表すことができます(コンピュータ内部では文字も数値として取り扱われています)。下の表は3つとも「A」を表しています。

指定方法 説明
文字 'A' 「'」で囲みます。
Unicode '\u0041' 16進数のUnicodeの前に「\u」をつけて「'」で囲みます。
数値 65 16進数のUnicodeを10進数に変換した数値で指定します。

文字列リテラル

文字列リテラルとは、(0文字以上の)複数の文字のまとまり(文字列)を表現するためのリテラルです。0文字を「空(から)文字」と呼びます。

指定方法 説明
文字列 "ABC" 「"」で囲みます。
Unicode "\u0041\u0042\u0043" Unicodeを「"」で囲みます。

「文字リテラル」でも少し触れたように、コンピュータ内部では文字1つ1つに番号が付けられています。この番号を文字コードといいます。ラテン文字語圏では、大小のアルファベットや数字、英文でよく使われるダブルクォーテーションマーク等、それほど数が多くないので、7桁の2進数で表すことのできるアスキー文字だけで十分です。しかし、日本語のように漢字等が数多くある言語では「7桁の2進数」では数が足りません。

そのため日本では独自の文字コード体系を考案したのですが、不幸にも複数の文字コード体系ができてしまい、プログラマを長い間悩ませてきました。その違いの多くはOSの違いによるものですが、一部時代とともに変わったりもしています。LinuxとMacのデフォルト文字コードはUTF-8ですが、Windowsのデフォルト文字コードはMS932です。つまり、Windowsのデフォルト文字コードでコーディングされたプログラムファイルをそのままMacでコンパイルすることができなかったりするわけです。

Javaコンパイラーのデフォルト文字コードはOSのものと一致していますが、コンパイルする時に変えることができます(コンパイルした後の「*.class」は文字コードの影響を受けません)。WindowsでMacやLinuxと同じUTF-8でコンパイルするには次のように、コマンドプロンプト上で文字コードを指定します。

      javac -J-Dfile.encoding=UTF-8 Greeting.java
   
   

Eclipseでは下の図のように「設定→一般→ワークスペース」の下の方の「テキスト・ファイルのエンコード」で変更できます。できれば、改行コードも意識しましょう(デフォルトは「Windows=CR + LF」、「Linux および MAC OS X=LF」、「Mac=CR」です)。

Windowsのデフォルト文字コードの変更

論理値リテラル

論理値(boolean)とは「真と偽」の2種類の値しかなく、真、偽をそれぞれ「true」、「false」で表現します。大文字(TRUE)で書いたり、ダブルクォーテーションで囲んだり(”false”)することはできません。

nullリテラル

nullは参照データ型(後述)に対して、オブジェクトが値を持たない(参照値を持たない)ことを示す特別なリテラルです。上で出てきた文字列の「”“(空文字)」とは別ものです。nullはオブジェクトの実態がないので、nullオブジェクトはメモリをほとんど消費しませんが、”“(空文字)はオブジェクトの実態があるので、それなりにメモリを消費します。

変数・定数とはTopへ

変数とは、ソースコード内で計算した値や人によって入力された値、データベースから取り出した値等、プログラム内で使用する値を保持するための値の入れ物です。変数という言葉は英語のvariable(変化するもの)の訳であるように、入れ物に入れる値を色々と変えることが可能です。一方、定数は英語のconstant(不変の,一定の)の訳で、一度値を入れるとその後はその値を変更することができないものを指します。例えば、円周率のような、変更させる必要がない(変更させてはならない)データを保持するのに利用されます。具体的な使い方は次の章で学習します。

またソースコード内では、複数の変数を使用できます。そのため、変数には名前をつけて他の変数と区別します。変数の名前のことを変数名と呼びますが、変数名をつける際にルールがあります。

命名ルール

変数名に限らず、後に紹介するクラスやメソッド等につける名前は、識別子と呼ばれています。識別子は数字や文字を組み合わせて、プログラマが自由に決められますが、いくつかのルールがあります。識別子の命名ルールは以下の通りです。

  1. 識別子の1文字目は、英字(a~z、A~Z)、ドル記号($)、アンダースコア(_)だけが許されています(数字もダメです)。
  2. 識別子の2文字目以降は数字も使用可能です(「-(ハイフン)」等の記号は使えません)。
  3. 予約語と同じ名前は使えません(下にある予約語の表を参照)。
  4. 大文字、小文字は厳密に区別されます。
  5. 文字数に制限はありません。
予約語一覧
abstract continue for new switch
assert default if package synchronized
boolean do goto private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while

※true、false、nullは予約語ではなく定数ですが使えません。

命名規約

先の識別子の命名ルールは守らないとコンパイルさえできません。しかしこれから紹介する「命名規約」というのは、守らなくてもコンパイルはできますが、コードの読みやすさ等を考慮して、そのグループ内で識別子の名前の付け方のルールを守りましょうね、というものです。

この命名規約は、ソースコードを記述する際のインデント量や「{」の位置、1行の文字数等を取り決めたコーディング規約と呼ばれる規約の一部です。各プロジェクトにおいて独自のコーディング規約を用意したりするので、絶対的なものというのは存在しません。また、Eclipseを使っているような場合、コードのフォーマットのルールをチーム内で共有することが可能です。

以下はJavaの基本的なコーディング規約の例です。これはOracle社のJavaプログラミング言語のためのコーディング規約の中の命名規約を参考にして書いたものです。

修飾子タイプ 命名規則
クラス クラス名は名詞にします。最初は大文字で書き始め、クラス名の中の単語と単語の間の頭文字を大文字にするというキャメルケースで書きます。クラス名はシンプルで意味がよくわかるようにしましょう。頭文字や省略語を使わず、単語全体を使いましょう(広く世間で使われているHTMLやURL等を除いて)。 class Calendar; class ImageToPDF;
インタフェース インタフェース名はクラス名に準じます。 interface AccessibleValue; interface DesktopManager;
メソッド メソッド名はキャメルケースで動詞を用いて命名しますが、最初の文字は小文字にします。 runFast(); getBackground();
変数 変数名は短いけれども、意味がよくわかるものにします。他の人が一見しただけで、その変数を使う意図がわかるようなものにすべきです。ただし、一時的に使って捨ててしまう(例えば、for文等で利用するような整数の「i,j,k,n」、文字ですと「c,d,e」の)ようなものを除いて、1文字変数は使わないようにしましょう。 double rate; float tdWidth;
定数 定数の名前は全て大文字で書き、アンダースコア(_)で単語と単語の間をつなぐ、いわゆるスネークケースで書きます。 int MIN_WIDTH = 4; int MAX_WIDTH = 999;

キャメルケースとスネークケースについて補足しておきます。「words counter」という2つの単語をつなげた名前で変数を作ろうとした場合、このままつなげたのでは「wordscounter」となって、読みづらくなります。したがって、単語と単語の間がわかるように、2つ目の単語の最初を大文字にして、つなげる方法をキャメルケースといい、単語と単語の間にアンダースコア(_)を挿入する方法をスネークケースといいます。

キャメルケース:wordsCounter

スネークケース:words_counter

そして、Javaではキャメルケースを使うのが一般的です。ただ、値を変えられない定数では、もともと全てを大文字で書く命名規約なので、キャメルケースでは書けず、スネークケースで書きます。例えば、URLが見つからない時、HTTPサーバーが返す404を入れておく定数はHTTP_NOT_FOUNDというようにJavaでは定義されています。

また、単語は通常英語を利用しましょう。日本語を使わないプログラマと一緒にコーディングするケースが増えてきている昨今、英語を使った方が無難です。ただし、例えば「担当者」という英語は「a person in charge」といいますが、これだと多くの日本人がわからないかもしれません。そのような場合は日本語を検討することもあり得るでしょう。

いずれにしろ、これらの規約は守らないとコンパイルできないというようなものではありません。コードをより読みやすいように、メンテナンスしやすいように、という意味ですので、プロジェクトに参加するメンバで意思統一しておくことが重要です。

データ型Topへ

Javaで変数を使うには、型を指定して宣言をする必要があります。型(データ型)にどのような種類があるのか、をみてみます。

型(データ型)を大きく分けると、基本型(基本データ型/プリミティブ型)と参照型に分けることができます。これらの性質を簡単にまとめると、次のようになります。

基本型 参照型
宣言、初期化して利用します。 宣言、「生成」、初期化して利用します。
種類としては数値と論理値(真と偽)と文字があり、数値は6種類あるので、全部で8種類になります(文字も文字コードという数字が入っているという意味では、数値が7種類ともいえます)。 配列型とクラス型とインタフェース型の3種類があります。クラス型・インタフェース型はプログラマがどんどん作ることが可能なので、事実上数えられないぐらいあるといえます。
変数に格納されるのは基本型の値そのものです。 変数に格納されるのは「参照値」とよばれるアドレス(メモリー内の場所を示す「番地」)で、その場所に、変数に代入しようとしたオブジェクトがあります。
参照型に比べメモリをあまり使いません。 基本型に比べ(オブジェクトを扱う分)メモリを多く使います。

基本型(基本データ型)

基本型には下の表のように8つあります。

ちなみに、下の表に出てきているバイト(byte)とは、ビット(bit)が8つあわさって表現する単位(1 byte = 8 bits)のことです。そして、そのビットとは2進数の一桁で「0か1」です。つまり8ビットというのは、2進数の8桁で表せる数値のことで「00000000」〜「11111111」の256(2の8乗)個の数字を扱えます。下の表で「byte型」は1バイト整数とありますが、マイナスの「-1〜-128」の128個、プラスの「1〜127」の127個と「0」を合わせて合計256個の整数を表します。

扱える数字の範囲
byte 1バイト整数(-128~127)
short 2バイト整数(-32768~32767)
int 4バイト整数(-2147483648~2147483647)
long 8バイト整数(-9223372036854775808~9223372036854775807)
float 4バイト単精度浮動小数点数(有効桁数が最低でも6桁)
double 8バイト倍精度浮動小数点数(有効桁数が最低でも15桁)
char 2バイト文字データ(\u0000~\uffff)
boolean 論理値 true(真)またはfalse(偽)

基本型の変数宣言と初期化

基本型の変数を利用するには「宣言」と「初期化」が必要です。「初期化」で代入する値の型に合わせて変数の宣言をしなければなりません。

変数宣言と初期化

変数宣言と初期化を一度にする場合と別々にする場合があります(初期化とは値を最初に代入することです)。以下がその例になります。

      int a = 1; // 宣言と初期化を一度に行う。
int b;
//....
b = 0; // 変数宣言とは別に初期化する。
   

「型名 変数名;」と宣言し、その後ろの別の場所で「変数名 = 値;」と初期化を後で行う。または「型名 変数名 = 値;」で同時に行います。 この時、さきに学習したリテラルの知識が必要になります。基本型に関係あるものを簡単にまとめたものが下の表です。

種類 進数 説明
整数 10進数 255, 12345L longの場合、整数の最後にLを書きます(intでは必要ありません)。
2進数 0b101 先頭に0b(ゼロ、ビー)を入れると2進数と判断されます。
8進数 0377 先頭に0(ゼロ)を入れると8進数と判断されます。
16進数 0xff 先頭に0x(ゼロ、エックス)を入れると16進数と判断されます。
小数 10進数 2.345, 1.234F floatを利用する時は数字の最後にFを書きます(doubleでは必要ありません)。
指数 2.4e-3 2.4×10の-3乗(「0.0024」)のことで、指数を表すeを使います(大文字可)。
文字 文字 'A' 「'」で囲みます。
Unicode '\u0041' 16進数のUnicordの前に「\u」をつけて「'」で囲みます。
数値 65 16進数のUnicodeを10進数に変換した数値で指定します。
論理値 true trueとfalseしか持てません
false

算術演算子

算術演算子は四則演算以外に「インクリメント(++)/デクリメント(––)」と呼ばれるものと、剰余(あまり算)を求める「%」があります。

演算子 記入例 説明
+ x + y xとyを加算します。
x – y xからyを減算します。
* x * y xをyで乗算します。
/ x / y xをyで除算します。
% x % y xをyで除算した余りを求めます。
++ インクリメント ++x x++ ++xはxを1増加させた後に文を評価します。 x++は文を評価した後に1増加させます。
–– デクリメント ––x x–– ––xはxを1減少させた後に文を評価します。 x––は文を評価した後に1減少させます。

また計算を行ったり、代入したりすると、型が自動で変わる場合がありますので、注意が必要です。

  1. 整数型と小数型の演算では、演算結果は小数型になります。
  2. 同じ整数型同士、小数型同士では、演算結果はサイズが大きい方になります。ただし、その場合でもbyte・short型等になることはなく、最低でもint型となります。
  3. 2.のため、byte型同士の演算であっても、演算結果はint型とみなされます。
  4. byte→short→int→long、float→double(型の大きさが大きくなる方向)の代入は暗黙に変換されます(基本型のワイドニング変換:widening primitive conversion)。
基本型の宣言、初期化、計算等の例
public class Primitives {
    public static void main(String[] args) {
        // byte
        byte binary1 = 0b10;// 10進数では2です。
        byte binary2 = 0b10;
        // byte同士の計算でも結果はint型になります。
        int answer1 = binary1 * binary2;// 2×2
        System.out.println(answer1);// 10進数で4と出力されます。
        // int
        int hexadecimal1 = 0xa;// 10進数では10です。
        int hexadecimal2 = 0xb;// 10進数では11です。
        int answer2 = hexadecimal1 * hexadecimal2;// 10×11
        System.out.println(answer2);// 10進数で110と出力されます。
        // short
        short decimal1 = 12;
        short decimal2 = 32767;
        // short同士の計算もintになります。
        int answer3 = decimal1 * decimal2;
        System.out.println(answer3); // 393204と出力されます。
        // long
        long decimal3 = 12345678912L; // Lを付けないとエラーになります。
        long decimal4 = 12345678912L;
        long answer4 = decimal3 * decimal4;
        System.out.println(answer4); // 4841835208525090816と出力されます。
        // byte->intは可能
        byte decimal5 = 10;
        int decimal6 = decimal5;
        decimal6 = decimal6 + 300; // エラーにならない(byteの最大は255)。
        System.out.println(decimal6); // 310と出力されます。
        // float
        float decimal7 = 123.456F; // Fが必要です。
        float decimal8 = 1F;
        float answer5 = decimal7 - decimal8;
        System.out.println(answer5); // 122.456と出力されます。
        // double
        double decimal9 = 123.456;
        double decimal10 = 12345.6789d; // dを書かなくてもOKです。
        double answer6 = decimal9 - decimal10;
        System.out.println(answer6); // -12222.2229と出力されます。
        // char
        char a = 'A'; // 直接シングルクォーテーションで代入ができます。
        char b = '\u0041'; // 16進数の41は65
        char c = 'あ';
        char d = '\u3042'; // 16進数の3042(10進数では12354)
        // char型は計算をさせると数字として扱われるようになる。
        int answer7 = a * b; // 65 × 65
        System.out.println(a); // Aと出力されます。
        System.out.println(a + 0); // 65と出力されます(16進数では41)。
        System.out.println(b); // Aと出力されます。
        System.out.println(b + 0); // 65と出力されます(16進数では41)。
        System.out.println(answer7); // 4225と出力されます。
        System.out.println(c); // 「あ」と出力されます。
        System.out.println(c + 0); // 12354と出力されます。
        System.out.println(d); // 「あ」と出力されます。

        // 型の自動変換(代入の場合)
        int decimal11 = 1;
        long decimal12 = decimal11; // 自動的にlong型に変換されます。
        decimal12 = decimal12 * 9223372036854775807L;
        System.out.println(decimal12); // 9223372036854775807と出力されます。
        // 型の自動変換(計算の場合)
        int decimal13 = 100;
        double decimal14 = 777.77;
        // decimal13はint型であるが、自動でdoubleになって計算される。
        double decimal15 = decimal13 + decimal14;
        System.out.println(decimal15); // 877.77と出力されます。
    }
}

基本型のキャスト

すでにbyte→short→int→long、float→double(型の大きさが大きくなる方向)の代入は暗黙に変換されること(プリミティブ型のワイドニング変換)には触れました。この反対の「型の大きさが小さくなる方向」への代入は、明示的に型を指定しないとコンパイルエラーとなります(プリミティブ型のナローイング変換:narrowing primitive conversion)。

すなわち、次のようなことをしようとしても、コンパイルができません。

コンパイルエラーになる代入
long a = 1000000L;
int b = a; // long型の値をint型に代入しようとしても、エラーになってコンパイルできません。

このような場合「キャスト」という方法でプログラマが意識的に型変換をすることができます。キャストは変換したい型を「( )」で囲み、変換元の変数の前に指定することにより行います。「(変換したい型) 変換元の変数;」です。

基本型のキャスト
long a = 1000000L;
int b = (int) a; // キャストをしているので、エラーになりません。

このように、プログラマがキャストをすることにより、能動的に型を変換することが可能です。

変換元の基本型 型変換が可能な変更先の基本型
boolean なし
char int, long, float, double
byte short, int, long, float, double
short int, long, float, double
int long, float, double
long float, double
float double
double なし

ただし、プリミティブ型のナローイング変換は、桁数の大きい型を小さい型に変換するわけなので、キャストするとおかしなことになってしまう場合があります。例えばlong型に格納されている値が「2147483647」より大きい時、int型(「2147483647」までしか取り扱えない)にキャストをしてもエラーにはなりませんが、予想外の数値になってしまうので、注意が必要です。このような現象をオーバーフローといいます。

無理なキャスト
long l = 2147483648L; // int型の最大値「2147483647」より1大きい数値です。
int i = (int) l;
System.out.println(i); // -2147483648と出力され、予想外な結果となります。

参照型

基本データ型以外の型全て(クラス型、配列型、インタフェース型等)が、この参照型になります。

基本データ型の変数の場合は、代入した基本データ型の値が変数という入れ物に直接格納されます。それに対して参照型の変数にオブジェクトを代入する時、オブジェクトそのものは変数という入れ物には格納されません。参照型の変数にはアドレス(オブジェクトの位置情報)が格納されます。オブジェクトについては後の章で学習しますので、ここでは1つだけ例に出して、説明しましょう。

Javaには文字列を代入できる基本データ型はありません(char型は1文字だけしか代入できません)。文字列は参照型であるString型、StringBuilder型等いくつかの型で取り扱うことができます。ここでは「StringBuilder」型で説明します。

次のソースコードには、まだ詳しくは学習していないクラスの使い方等が出てきています。全てを理解する必要はありませんが、次の何点かを押さえておきましょう。

  1. クラスをオブジェクト化するには「new クラス名()」を使い、その生成したオブジェクトのアドレスを受け取るためには、変数の前にクラス名を型として宣言します。すなわち、参照型の場合は、基本型と違い(宣言→初期化)、宣言→生成→初期化となります。

    StringBuilder str = new StringBuilder(); // 宣言    初期化 生成

  2. StringBuilderクラスではメソッドを使って、文字列を追加できますが、その方法は「オブジェクトのアドレスを格納した変数.append(“文字列”);」です。

    str.append(“abc”);

  3. 「System.out.println(StringBuilderオブジェクト)」でStringBuilderオブジェクト内の文字列を出力できます。

    System.out.println(str);

じっくり次のソースコードを読んでみて下さい。

基本型と参照型の違い
 1 public class ReferenceExample {
 2     public static void main(String[] args) {
 3         // 基本型の場合
 4         int decimalA = 10;
 5         // decimalBにdecimalAを代入→値そのものがコピーされる
 6         int decimalB = decimalA;
 7         // decimalBに1を加える
 8         decimalB = decimalB + 1;
 9         System.out.println("decimalA = " + decimalA); // decimalAは10のまま
10         System.out.println("decimalB = " + decimalB); // decimalBは1足されて11
11 
12         // 参照型の場合
13         // クラス型(StringBuilder型)は「new」でオブジェクトを生成します。
14         StringBuilder str = new StringBuilder();
15         StringBuilder str2; // str2というStringBuilder型の変数を宣言(初期化をしていない)。
16         StringBuilder str3 = new StringBuilder();
17         str.append("abc"); // strという変数にabcという文字列を追加します。
18         System.out.println(str); // abcが出力されます。
19         // str2にstrを代入→strの指しているオブジェクトのアドレスがstr2にコピーされます。
20         str2 = str;
21         // コピーされたstr2に文字列defを追加。
22         str2.append("def");
23         str3.append("abcdef"); // str3にabcという文字列を追加します。
24 
25         // strもstr2も取り扱っているオブジェクトは同じなので、同じ文字列が出力されます。
26         System.out.println("str = " + str); // abcdefが出力
27         System.out.println("str2 = " + str2); // abcdefが出力
28         System.out.println("str3 = " + str3); // abcdefが出力
29         System.out.println(str == str2); // trueが出力
30         System.out.println(str == str3); // falseが出力
31     }
32 }

以下のように出力されます。

      decimalA = 10
decimalB = 11
abc
str = abcdef
str2 = abcdef
str3 = abcdef
true
false
   

上のソースを図示すると次のようになります。

基本型の場合

基本型の場合は、decimalAに10を代入し、その後そのdecimalAをdecimalBに代入した時、値自体がコピーされ、decimalBに値が格納されます。つまり、10という値が2ヵ所に存在し、それぞれdecimalAとdecimalBに格納さていることになります。

一方、参照型の場合、strに「abc」という文字列を追加し、そのstrをstr2に代入した時、基本型とは違い「abc」という文字列自体はコピーされません。コピーされるのはアドレスの値です。つまりオブジェクト自体はコピーされないので一つしか存在しませんが、同じオブジェクトを参照している変数が二つになります。したがって、「str2.append(“def”);」でstr2の方に文字列「def」を追加すると、同じオブジェクトを指しているstrの方も変化してしまうわけです。この違いは重要ですので、しっかり理解しておきましょう。

参照型の場合

定数の宣言と初期化

変数はその名の通り、刻々と変わる値を扱うことができますが、固定された値を扱いたい時もあります。例えば、円周率を入れておく変数が用意してあり、誰かが間違って書き換えてしまったりすると、多くの場合問題が起こります。そこで、ソースコード内でこれを定数として宣言し、一度初期化したら二度とその値を変更できないようにする(しようとするとコンパイルエラーが起こります)ことが可能で、宣言時にfinal修飾子を付けることで実現できます。見た目は変数の場合とほとんど同じなので(finalが付いているだけ)、定数名は大文字にし、すぐわかるようにするという命名規則が多いようです。

   final データ型 定数名 = 初期値;

定数宣言と初期化
 1 public class Constants {
 2     public static void main(String[] args) {
 3         final int BASE_YEAR = 1970; // finalで定数になる
 4         System.out.println(BASE_YEAR);
 5         // BASE_YEAR = 1960;
 6         final int MY_BIRTHDAY_YEAR;
 7         MY_BIRTHDAY_YEAR = 1959; // 宣言行で初期化しなくても良いが、最初にしてしまった方が無難です。
 8         System.out.println(MY_BIRTHDAY_YEAR);
 9     }
10 }

上のソースの「// BASE_YEAR = 1960;」の「//」を取ると、再代入になるのでコンパイルができなくなります。また、宣言した際に同時に初期化しなくてもエラーにはなりませんが、別のプログラマーが別のクラスから定数を先に間違った値で初期化してしまう可能性等もあり、宣言と同時に初期化しておいた方が無難です。

スコープ

変数は、使用する前に宣言する必要があります。しかし、変数は宣言した場所によって、その変数を使用できる範囲が制限されます。これを有効範囲(スコ ープ)と呼び、プログラマはこれに十分注意する必要があります。

Javaでは「{」と「}」との間のことをブロックといいますが、このブロック内で宣言された変数は、そのブロックの外では参照できないのです。次のソースコードをみてください。int型の変数insideはブロックの中で宣言され、初期化されています。しかし下のコメント部分の「// inside = 200;」の「//」を取ると、コンパイルできません。もしEclipseをお使いでしたら、赤い波線が出るはずです。 ブロックの外側からはinside変数はスコープ外で見えないのです。

基本型と参照型の違い
1 public class ScopeSample {
2     public static void main(String[] args) {
3         {
4             int inside = 100;
5         }
6         // inside = 200; // コメントを取るとコンパイルができません。
7     }
8 }

このブロックが出てくるのは、次章の「演算子と分岐文」のif文や「繰り返し文と繰り返し制御文」のfor文なので、スコープの詳細はその時に解説します。

  created at:29 June 2015




[投稿する]場合は、 枠の中の図形をマウスでドラッグして、(あるいは指で)なぞって下さい。それほど厳密でなくても大丈夫です。