2.7 リテラル
2.7.1 整数リテラル
リテラルとは、見たまま、そのままの値のトークンです。例えば 10 という数字や "Kitty" といった文字列など、ソース上に直接記述された情報はリテラルに分類されます。リテラルの値はコンパイル時に確定し、実行中に変化することはありません。
とはいうものの、実は、変数と同様にリテラルにも型が存在します。意味は変数かリテラルかの違いだけであり、型の考え方はまったく同じです。10 であれば整数型、0.1 であれば浮動小数点型となります。もちろん、リテラルを変数に保存する場合、型が一致しなければなりません。
int iValue = 0.1;
この場合、整数型に浮動小数点型のリテラルで初期化しようとしているため、コンパイラはエラーを発生させます。
小数点を含まない数字は整数リテラルと呼ばれ、整数型の変数に代入することができます。「2.6 変数と型」でも iValue = 10 という文で整数リテラルを使いました。このとき、整数リテラルは int 型として認識されています。
しかし、231 以上の数値を表現したい場合、int 型では不十分なので long 型として認識されなければなりません。long 型の整数リテラルを記述するには、数字の末尾に l または L を付加します。ただし、小文字の l は数字の 1 と誤解しやすいため、大文字の L を使うべきと考えられています。long 型であれば 263 までの値を表現することが可能です。
long lValue = 2147483648L;
この場合、整数リテラルの末尾に L の文字が付加されているため、数値は long 型、64ビットとして処理されます。L が無い場合は int 型、32ビットとして処理されますが、32ビットでは 0 から 2147483647 までしか表現できないのでコンパイル・エラーとなることでしょう。このような、リテラルの末尾に付加する文字を型接尾辞と呼びます。
class Test { public static void main(String args[]) { long lValue = 2147483648L; System.out.println(lValue); } }
>java Test 2147483648
コード1は L 型接尾辞を指定した整数リテラルで long 型の変数を初期化しています。型接尾辞を削除してコンパイルすれば、エラーが検出されることを確認できます。
しかし、このような大きい数を扱う場合は 10 進数だと不便な場合がしばしばあります。また、コンピュータの世界は 2 進数で物事を考えていくため、8 進数や 16 進数を使ったほうが便利な時もあることでしょう。整数リテラルは 8 進数や 16 進数で表現することも可能です。
何も指定しない場合は、これまで記述してきたように10進数として解釈されますが、整数リテラルの先頭に 0x を指定すれば 16 進数、0 から始まり 0 ~ 7 までの数字だけで2桁以上の場合は 8 進数であると解釈されます。
class Test { public static void main(String args[]) { int iHex = 0xFF; System.out.print("iHex = "); System.out.println(iHex); int iOct = 0377; System.out.print("iOct = "); System.out.println(iOct); } }
>java Test iHex = 255 iOct = 255
コード2は 16 進数と 8 進数の整数リテラルを使っています。16 進数 FF も、8 進数 377 も、10進数の 255 に等しく、実行結果を見れば確認できます。一桁の 0 は 10 進数であると解釈されますが0、00、0x0 はすべて同じ値なので、それが問題になることはありません。
2.7.2 浮動小数点数リテラル
float や double 型の定数は浮動小数点数リテラルと呼ばれ、整数部、小数点、小数部、指数部、型接尾辞で構成されます。浮動小数点数リテラルは、必ず小数点か指数のいずれかが必要で、それ以外は省略することができます。
整数部 . 小数部 E 指数部 型接尾辞
小数点は ASCII 文字のピリオド . で表され、その後に小数部が続きます。指数部をが存在する場合は ASCII 文字の e または E のいずれかを指定し、その後に整数が続きます。例えば、次のトークンはすべて浮動小数点数リテラルであると解釈されます。
- 3.14
- 1.
- .123
- 0.0
- .314e1
- 31.4E-1
- 314e-2
- 1e1
これらの浮動小数点数リテラルは、整数リテラルとは異なり10進数でのみ表記できます。
浮動小数点数リテラルもまた、型接尾辞を指定することで float 型なのか double 型なのかを区別することができます。float 型であることを表す場合は f または F、double 型であることを表す場合は d または D をリテラルの末尾に指定します。接尾辞がない場合は double 型であると解釈されるため float 型変数に浮動小数点数リテラルを代入する場合は接尾辞に f または F を指定しなければなりません。特別な理由がない限り、接尾辞 d または D を指定する必要はありません。
class Test { public static void main(String args[]) { float fValue = 3.14F; System.out.print("fValue = "); System.out.println(fValue); double dValue = 3141592653589793e-15; System.out.print("dValue = "); System.out.println(dValue); } }
>java Test fValue = 3.14 dValue = 3.141592653589793
コード3は float 型と double 型の変数を用意し、それぞれ適当な値で初期化してそれを画面に表示します。float 型の注意点としては、浮動小数点数リテラルに型接尾辞 F を指定している点です。これがなくては、コンパイル・エラーとなってしまいます。
2.7.3 文字と文字列リテラル
Java では、文字が Unicode として扱われることを説明しました。C 言語の char 型変数は ASCII 文字を表すための 1 バイトでしたが、Java 言語の char 型は 2 バイトであることに注意してください。
char 型で表現できる 1 つの Unicode 文字を文字リテラルと呼びます。混同しがちですが、文字と文字列は異なる存在であることを認識して下さい。文字リテラルと表現された場合は常に 1 つの Unicode であり、複数の文字の並びが文字列となります。これは、まったく異なる型であると解釈されます。
文字リテラルは Unicode 文字を引用符 ' で囲みます。引用符がない場合は識別子として認識されてしまうため、文字がリテラルであることを証明するために引用符で囲む必要があるのです。文字リテラルは常に char 型となります。引用符の間に行末記号(改行)が存在する場合はエラーとなります。
class Test { public static void main(String args[]) { char cValue = '猫'; System.out.print("cValue = "); System.out.println(cValue); } }
>java Test cValue = 猫
ここで、コンピュータの世界では文字も数値で表現されているということを思い出してください。char 型は Unicode 文字を表す型ですが、実体は 16 ビットの負数を表現しない整数型として分類されています。そのため、他の整数型と組み合わせた計算処理が可能となっています。
文字コードを数字として処理することは、コンピュータの言語処理において重要です。例えば ASCII 文字の A は 0x41、B は 0x42、C は 0x43 と昇順に並んでいます。これを数値として分析することができれば、プログラム的に文字を整列させることができるのです。char 型が整数型に分類されるのは、こうした利用が考えられるためです。
class Test { public static void main(String args[]) { char cValue = 0x0041; System.out.print("cValue = "); System.out.println(cValue); } }
>java Test cValue = A
コード5は実に興味深いプログラムです。char 型変数 cValue には整数リテラル 0x41 を代入しているにもかかわらず、その結果は A という文字を表示されました。
char 型の変数に整数リテラルを代入できる理由は、char 型が整数型に分類されるということから理解できるでしょう。そして、print() 及び println() メソッドは char 型のデータを受けると、それを文字として表示する性質があるため、結果は値に関連付けられている Unicode 文字となるのです。実は、これとまったく逆の現象を発生させることも可能です。
int iValue = '猫';
代入先の変数は int 型ですが、これは構文上、何の問題もありません。iValue 変数には Unicode 文字 '猫' を示すコード 0x732B が格納されます。
文字リテラルは 1 文字しか表せません。「Kitty on your lap」のような分の場合はどうでしょうか?文を表現するには文字列リテラルを使います。文字列リテラルは二重引用符を使って Unicode キャラクターの並びを囲みます。文字リテラルと同様に、引用符の間に行末記号が存在する場合はコンパイル・エラーとなります。
文字列リテラルは2.1 はじめてのJava言語 コード1以来、何度も使ってきたので説明不要でしょう。
2.7.4 エスケープ・シーケンス
文字や文字列リテラルは、引用符の間で改行することはできません。改行を表現したい場合、また、文字列リテラルの中に二重引用符や水平タブを使いたい場合も同様です。
このように文字としては表現が難しい「'」「"」のような記号、表示できない文字などを表現したい場合はエスケープ・シーケンスを使います。エスケープ・シーケンスはバックスラッシュ \ (\u005C) とそれに続く ASCII 文字で構成されます。これを使えば、文字リテラルで改行や引用符を表現することができるようになります。
エスケープ・シーケンス | Unicode | 意味 |
---|---|---|
\b | 0008 | バックスペース |
\t | 0009 | 水平タブ |
\n | 000A | 改行 |
\f | 000C | フォーム・フィード |
\r | 000D | 復帰 |
\" | 0022 | 二重引用符 |
\' | 0027 | 引用符 |
\\ | 005C | バックスラッシュ |
\XXX | 0000~00FF | 00~FF までの8進数で表現されたコード XXX は8進数値 |
エスケープ・シーケンスはこれで 1 つの文字と解釈されるため、文字リテラルとして指定することも可能です。Unicode エスケープとは異なり、コンパイルの字句変換サイクルで処理されるわけではありません。コンパイラがエスケープ・シーケンスを処理するころには、すでに \u は変換済みであることに注意してください。
文字、または文字列リテラル内の \ に続く文字が表1以外のものであればコンパイル・エラーとなります。バックスラッシュそのものを指定したい場合はエスケープ・シーケンス \\ を使うように注意してください。
class Test { public static void main(String args[]) { String str = "\"Kitty\n\ton your lap\""; System.out.println(str); } }
>java Test "Kitty on your lap"
コード6は、エスケープ・シーケンスを使って文字列リテラル内に二重引用符、改行、水平タブを指定しています。これらはエスケープ・シーケンスを使わなければソース上で表現できないものです。特に、改行や水平タブは文書のレイアウト的な問題などでよく使います。
2.7.5 真偽リテラル
「YESかNOかで、お答えください」という二者択一的な情報を表すには、文字や数値ではなく boolean という型で表現します。boolean 型の変数には ASCII 文字で表現される true または false のいずれかを代入することができます。この true と false を真偽リテラルと呼びます。
boolean 型が表す真偽値は「Chapter3 フロー制御」で多用することになりますが、これはプログラムの流れを決定する重要な材料となります。「true ならば…を実行し、そうでなければ…を実行しなさい」といった制御を行うことができるようになるのです。
class Test { public static void main(String args[]) { boolean blValue = true; System.out.print("blValue = "); System.out.println(blValue); } }
>java Test blValue = true
コード7は真偽リテラル true を boolean 型の変数 blVlaue に代入し、これを表示するプログラムです。本来、真偽値はプログラムの流れを制御するためのものであり、このプログラムを見ただけでは、何のための真偽リテラルなのか理解に苦しむかもしれません。これはフロー制御を学習した時にその意義を理解することができるでしょう。
2.7.6 null リテラル
このほかに、変数が保持する情報が存在しないということを表す特殊な null 型という値が存在します。null 型は唯一、null という値を保持し、ASCII 文字を用いた null リテラルは常に null 型となります。null は、数値型の変数に代入することはできません。null を代入できるのは、何らかのオブジェクトの位置を表す参照型と呼ばれるタイプの変数だけです。
例えば String 型は参照型に分類されるため、null を代入することができます。
String str = null;
ただし、null は「情報が存在しない」ことを表すものなので、null を格納している変数を使うことはできません。