リテラルの罠

リテラルの罠

このレッスンでできるようになること。アンダースコア区切り、2進・8進・16進のリテラル、そして char と int の関係を見分けられるようになります。

まず予測してください

次のコードは何を表示するでしょうか。そもそもコンパイルが通るかどうかから考えてください。

int a = 0b1010; int b = 017; int c = 0x1F; int d = 1_000_000; char e = 65; System.out.println(a + " " + b + " " + c + " " + d + " " + e);

答えと理由

表示されるのは 10 15 31 1000000 A です。順に見ていきます。

  • 0b1010 は2進数です。1010 は 8 + 2 なので 10 になります。0b は Java 7 から使えます
  • 017 は8進数です。ここが最大の罠で、先頭の 0 だけで8進になります。17 でも 0x17 でもなく、1×8 + 7 で 15 です。日付や時刻を int month = 08; のように書くと、8 は8進の数字として存在しないのでコンパイルエラーになります
  • 0x1F は16進数です。1×16 + 15 で 31 になります。0X1f のように大文字小文字を混ぜても同じ値です
  • アンダースコアは桁区切りで、値には一切影響しません。1_000_000 はただの 1000000 です
  • char e = 65; は 'A' になります。 char は数値型の一種で、int の定数が char の範囲に収まっていれば代入できます

アンダースコアを置けない場所

アンダースコアは「数字と数字のあいだ」にしか置けません。次はすべてコンパイルエラーです。

int x1 = _1000; // 先頭には置けない。しかもこれは変数名として読まれる int x2 = 1000_; // 末尾には置けない double x3 = 1_.5; // 小数点の隣には置けない double x4 = 1._5; // 小数点の隣には置けない int x5 = 0_x1F; // 進数の接頭辞の途中には置けない long x6 = 100_L; // 接尾辞の隣には置けない

逆に int ok = 0b1010_1010;long ok2 = 1_000_000_000_000L; は問題なく通ります。アンダースコアが連続していても通ります。 1__000 は合法です。ここを「連続は不可」と読ませる選択肢がよく出ます。

L 接尾辞

int の範囲を超えるリテラルには L が要ります。long big = 10000000000; は、まず int のリテラルとして読まれてから範囲外と判定されるのでコンパイルエラーです。10000000000L と書けば通ります。小文字の l も文法上は使えますが、数字の 1 と見分けがつかないため試験でもわざと紛らわしく出されます。

char と int の行き来

char を計算に使うと int に昇格 します。だから char c = 'A'; System.out.println(c + 1);B ではなく 66 を表示します。文字として出したければ (char)(c + 1) とキャストし直す必要があります。一方 System.out.println("" + c + 1); は文字列の連結になるので A1 です。この3つの違いが、そのまま選択肢として並びます。

まとめ

先頭の 0 は8進、アンダースコアは数字と数字のあいだだけ、char は計算すると int になります。この3つを押さえておけば、リテラルの出題は取り切れます。

要件

  1. 0b1010 / 017 / 0x1F / 1_000_000 の4つのリテラルをそのままの表記で使うこと
  2. char 型の変数に 65 を代入すること
  3. char そのものと、char に 1 を足した結果の両方を文字列に含めること
  4. 6つの項目を半角スペース1つでつないだ文字列を返すこと

入出力例

literals()"10 15 31 1000000 A 66" literals()"10 15 31 1000000 A 66"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.java
学習モード

メモ

リテラルの罠

⌘S で保存