3.2 リテラル（数値リテラル、文字リテラル、文字列リテラルなど）～Java Basic編

### はじめに

#### 自己紹介

皆さん、こんにちは、Udemy講師の斉藤賢哉です。私はこれまで、25年以上に渡って企業システムの開発に携わってきました。特にアーキテクトとして、ミッションクリティカルなシステムの技術設計や、Javaフレームワーク開発などの豊富な経験を有しています。
様々なセミナーでの登壇や雑誌への技術記事寄稿の実績があり、また以下のような書籍も執筆しています。
* [「マスタリング Java EE 5」（2007年）](https://amzn.asia/d/j0txqK5)
* [「アプリケーションアーキテクチャ設計パターン」（2017年）](https://amzn.asia/d/9avaCyF)

いずれも**Java EE**（**Jakarta EE**）を中心にした企業システム開発のための書籍です。中でも [「アプリケーションアーキテクチャ設計パターン」](https://amzn.asia/d/9avaCyF)は、（Javaに限定されない）比較的普遍的なテーマを扱っており、内容的にはまだまだ陳腐化していないため、興味のある方は是非手に取っていただけると幸いです（中級者向け）。

#### Udemy講座のご紹介

この記事の内容は、私が講師を務めるUdemy講座『**Java Basic編**』の一部の範囲をカバーしたものです。『**Java Basic編**』はこちらの[**リンク**](https://www.udemy.com/course/learn-java-se-basic/?referralCode=594C958456356851C97C)から購入できます（セールス対象外のためいつも同じ価格）。また**定価の約30%OFFで購入可能なクーポン**をQiita内で定期的に発行していますので、興味のある方は、ぜひ私の他の記事をチェックしてみてください。

この講座は、以下のような皆様にお薦めします。
* Javaの言語仕様や文法を正しく理解すると同時に、現場での実践的なスキル習得を目指している方
* 新卒でIT企業に入社、またはIT部門に配属になった、新米システムエンジニアの方
* 長年IT部門で活躍されてきた中堅層の方で、学び直し（リスキル）に挑戦しようとしている方
* 今後、フリーランスエンジニアとしてのキャリアを検討している方
* 「**Chat GPT**」のエンジニアリングへの活用に興味のある方
* 「**Oracle認定Javaプログラマ**」の資格取得を目指している方
* IT企業やIT部門の教育研修部門において、新人研修やリスキルのためのオンライン教材をお探しの方

#### この記事を含むシリーズ全体像

この記事はJava SEの一部の機能・仕様を取り上げたものですが、一連のシリーズになっており、**シリーズ全体でJava SEを網羅**しています。また認定資格である「**Oracle認定Javaプログラマ**」（Silver、Gold）の範囲もカバーしています。シリーズの全体像および「Oracle認定Javaプログラマ」の範囲との対応関係については、以下を参照ください。

https://qiita.com/KenyaSaitoh/items/4711a078a851510bc4da

## 3.2 リテラル

### チャプターの概要

このチャプターでは、リテラル、すなわち様々なデータの「表記方法」について学びます。

### 3.2.1 リテラル

#### リテラルとは

リテラルとは変数に格納する値の「表記方法」です。
リテラルには、データ型の種類に応じて以下のような種類があります。
* 論理リテラル
* 整数リテラル（数値リテラル）
* 浮動小数点リテラル（数値リテラル）
* 文字リテラル
* 文字列リテラル

#### 論理リテラル

ここではまず論理リテラルについて説明します。
論理リテラルとは、論理型であるboolean型が保持する2種類の値、真と偽の値を表すための表記方法です。具体的には、真についてはtrue、偽についてはfalseになります。いずれもすべて小文字で表され、クォーテーション等で囲んではいけません。

#### 整数リテラル

数値リテラルは、大きく整数リテラルと浮動小数点リテラルに分けられます。
このうち整数リテラル、すなわち整数の表現方法には、10進数リテラル、16進数リテラル、2進数リテラル、8進数リテラルといった種類があります。
以下のコードは、いずれも整数200の表記方法です。

```java:snippet_1 (Main_3_2)
int x1 = 200; // 10進数リテラル
int x2 = 0xC8; // 16進数リテラル
int x3 = 0b11001000; // 2進数リテラル
int x4 = 0310; // 8進数リテラル
```

通常のJavaによるアプリケーション開発では、整数を扱う場合、殆どのケースにおいて、10進数リテラルを使用することになるでしょう。

#### 浮動小数点リテラル

次に浮動小数点リテラルです。
浮動小数点数は、整数部と小数部を組み合わせてシンプルに表記するのが一般的ですが、「指数表現」を利用することも可能です。指数表現では、数値の末尾に"e"と掛け合わせる10の乗数を記述します。すなわち、"e3"は1000倍する、という意味になります。
以下のコードは、いずれも123.4567の表記方法です。

```java:snippet_2 (Main_3_2)
double d1 = 123.4567; // 整数部と小数部の組み合わせによる表記
double d2 = 0.1234567e3; // 指数表現
double d3 = .1234567e3; // 指数表現（先頭の0は省略可能）
```

#### 数値セパレーター

日常生活では、数値を表記する際、読みやすさの観点から3桁ごとにカンマで区切るのが一般的です。
Javaでも桁数の大きな数値の可読性向上のために、数値リテラルの中に、数値セパレーターとして、"_"（アンダースコア）を入れることができます。数値セパレータは、数値の前や小数点の直後などを除き任意の位置に入れることができますが、特別な理由がない限りは3桁ごとに入れるのがよいでしょう。
以下のコードは、いずれも整数1234567の表記方法です。

```java:snippet_3 (Main_3_2)
int x1 = 1234567;
int x2 = 1_234_567;
```
また数値セパレーターは、浮動小数点型にも適用可能です。
以下のコードは、いずれも123.4567の表記方法です。

```java:snippet_4 (Main_3_2)
double d1 = 123.456_7; // 整数部と小数部による表記
double d2 = .1_234_567e3; // 指数表現
```

### 3.2.2 文字リテラルと文字列リテラル

#### 文字リテラル

ここでは文字リテラルについて説明します。
文字リテラルとは、単一の文字を表すための表記方法です。
単一の文字は、以下のようにシングルクォーテーションで囲んで表現します。

```java:snippet_5 (Main_3_2)
char c = 'ア';
```

#### 文字列リテラル

次に文字列リテラルです。
文字列リテラルとは、文字列、すなわち1つ以上の文字の連続を表すための表記方法です。
文字列は、以下のようにダブルクォーテーションで囲んで表現します。

```java:snippet_6 (Main_3_2)
String str = "foo";
```

#### エスケープシーケンス

文字リテラルおよび文字列リテラルには、エスケープシーケンスと呼ばれる特殊な記法があります。
エスケープシーケンスは`¥～`という記法で、具体的には以下のような種類があります。

【表3-2-1】エスケープシーケンスの種類
|エスケープシーケンス|説明|
|--|--|
|`¥t`|タブ文字|
|`¥n`|改行（ラインフィード）|
|`¥r`|復帰（キャリッジリターン）|
|`¥f`|フォームフィード（改ページ）|
|`¥'`|シングルクォーテーション|
|`¥"`|ダブルクォーテーション|
|`¥\`|バックスラッシュ|

この中で、例えば`¥t`というエスケープシーケンスはタブ文字を表します。
従って以下のコードを実行すると「a    b」（aとbの間にタブ文字あり）と表示されます。

```java:snippet_7 (Main_3_2)
String str = "a¥tb";
System.out.println(str);
```

またクォーテーションは、文字リテラルや文字列リテラルの区切り文字として利用されるため、文字としてクォーテーションを扱いたい場合はエスケープシーケンスを使用します。
従って以下のコードを実行すると「'foo'」と表示されます。

```java:snippet_8 (Main_3_2)
String str = "¥'foo¥'";
System.out.println(str);
```

:::note warn
エスケープシーケンスのための`¥`は、OSによって異なります。Windowsの場合は`¥`ですが、macOSやLinuxの場合は「バックスラッシュ」になります。
:::

### 3.2.3 長い文字列とテキストブロック

#### 長い文字列の取り扱い

1つの文字列が長くなりすぎてしまった場合は、文字列を分割しコード上で改行することによって可読性を確保するのが一般的です。
分割された文字列は、`+`演算子[^1]によって連結することができます。具体的には以下のコードを見てください。

```java:snippet_9 (Main_3_2)
String str1 = "こんにちは！私はAlice、25歳です。日本語を話せます。"; //【1】
String str2 = "こんにちは！私はAlice、25歳です。" + //【2】
        "日本語を話せます。";
```

もし【1】のように文字列が長くなってしまい、コードの可読性低下が懸念される場合は、【2】のように文字列を分割して改行した上で、適切にインデントを入れるようにします。ただしここでの改行は、あくまでもコード上の「体裁」としての改行であって、文字列そのものに改行が入るわけではありません。

#### 文字列の中における改行

ここでは文字列そのものに改行を入れる方法について説明します。
文字列リテラルの中でそのまま改行すると、「ダブルクォーテーションが正しく閉じられていない」と見なされてコンパイルエラーになります。

```java:snippet_10 (Main_3_2)
String str = "こんにちは！私はAlice、25歳です。
        日本語を話せます。"; // コンパイルエラー
```

このような場合は、エスケープシーケンスの"¥n"を利用します。

```java:snippet_11 (Main_3_2)
String str = "こんにちは！私はAlice、25歳です。¥n日本語を話せます。";
```

ただしこの表記方法では、長い文字列を表現しようとすると、可読性が大きく劣化します。このような場合は、次に取り上げるテキストブロックを利用すると良いでしょう。

#### テキストブロックとは

テキストブロックは、複数行にまたがる文字列を簡潔に表記するための機能で、Java 15でサポートされました。
テキストブロックを利用するためには、単一のダブルクォーテーションの代わりに、3つの連続したダブルクォーテーションを使用します。
具体的には、以下のようなコードになります。

```java:snippet_12 (Main_3_2)
String str = """
        こんにちは！私はAlice、25歳です。
        日本語を話せます。
        """;
```

開始を表す`"""`から終了を表す`"""`までの間に、任意の文字列を記述できます。このとき、コード上の改行がそのまま文字列の改行と見なされます。また開始を表す`"""`は、コード上において直後に改行を入れる必要があるため、注意してください。
なおテキストブロックを一種のテンプレートと見なし、後から任意の変数を埋め込みたい（例えばこの例では「Alice」や「25」などの部分を変数として埋め込む）というケースがあります。そのような場合は、文字列のフォーマッティング機能（レッスン16.1.3参照）を利用してください。

#### テキストブロックにおけるインデント

テキストブロックにおけるインデントには、付随的なインデントと、明示的なインデントがあります。付随的なインデントとは、コードの可読性確保のためのインデントで、明示的なインデントとは、開発者によって意図された文字列そのもののためのインデントです。
具体的には、以下のコードを見てください。

```java:Main_TextBlock.java
public class Main_TextBlock {
    public static void main(String[] args) {
        String str = """
               こんにちは！
                   私はAlice、25歳です。
           日本語を話せます。
               """;
        System.out.println(str);
    }
}
```

テキストブロックでは、文字列の左端は、記述された文字列の中で最も浅い位置になります。この例では「日本語」と記述されている位置です。「日本語」を左端としたとき、それよりも左側の空白は付随的なインデントと見なされ、この文字列の内容には影響はしません。一方「日本語」を左端としたとき、それよりも右側の空白は明示的なインデントと見なされ、この文字列の内容に影響します。
従って、このコードを実行すると以下のように表示されます。

```
    こんにちは！
        私はAlice、25歳です。
日本語を話せます。
```

なお終了を表す`"""`の位置も、付随的なインデントを決める際の因子となります。つまり終了を表す`"""`が最も浅い位置にあると、そこが左端となりますので注意してください。

### このチャプターで学んだこと

このチャプターでは、以下のことを学びました。

1. リテラルには、数値リテラル、論理リテラル、文字リテラル、文字列リテラルといった種類があること。
1. 整数における10進数、16進数、2進数、8進数リテラルの表記方法について。
1. 浮動小数点のリテラルや指数表現について。
1. 数値セパレータについて。
1. 文字リテラル、文字列リテラルの表記方法について。
1. 長い文字列の取り扱いや、Java 15でサポートされたテキストブロックについて。

[^1]:`+`演算子は算術演算子（チャプター4.1）の1つだが、文字列を連結するためにも使用する。