文字列の連結

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

文字列の連結 とは

Java+ 演算子で文字列同士、文字列と数値、boolean を繋げる方法と、評価順序の罠を学ぼう。

文字列を + でつなぐ

プログラムでは「商品名と価格をまとめて 1 行で表示する」「ユーザー名と年齢を結合して "田中さん (25)" のような表示にする」など、複数の値をくっつけて 1 つの文字列を作る場面が山ほどあります。Java ではこれを + 演算子 1 つで実現できます。算術演算で覚えた + が、文字列に対しては「連結」の意味になるという、ちょっと不思議な性質を持っているのです。

Java

String hello = "こんにちは、" + "田中さん"; // → "こんにちは、田中さん"

Java+ は「数値同士なら足し算、文字列が混ざると連結」と覚えてください。String 型がひとつでも式に含まれると、+ の意味が一気に「文字列連結」へ切り替わります。これは初心者がもっとも驚き、もっとも便利だと感じる仕様のひとつです。

左右どちらかが String であれば、もう片方が int でも double でも boolean でも勝手に文字列に変換 (自動変換) して連結してくれます。コードを書く側からすると、いちいち変換関数を呼ばなくて済むのでとても楽です。

数値や boolean との連結

Java+ は文字列と数値 (int double long)、文字列と boolean も連結できます。連結時には自動的に数値や boolean が文字列表現に変換されます。

Java

String a = "価格は " + 100 + " 円"; // → "価格は 100 円" String b = "円周率は " + 3.14; // → "円周率は 3.14" String c = "在庫あり? " + true; // → "在庫あり? true" String d = "文字 " + 'A' + " の隣は " + 'B'; // → "文字 A の隣は B"

見てのとおり、100 3.14 true 'A' のような値も + の隣に String があれば、すべて勝手に文字列化されます。Pythonf-stringJavaScript のテンプレートリテラルに比べると、Java は少し古風な書き方ですが、この + 連結が一番素直で読みやすいので最初はこれを覚えれば十分です。

「数値を文字列にする」のために String.valueOf(100)Integer.toString(100) という関数も用意されていますが、+ の隣に String を置くだけで自動的にやってくれるので、明示的に呼ぶ場面はほとんどありません。

String.format と String.concat

+ 以外にも、文字列を組み立てる方法がいくつかあります。今は「こんなのがあるのか」と眺めるだけで構いません。

Java

String s1 = String.format("商品名: %s, 価格: %d円", "ペン", 100); // → "商品名: ペン, 価格: 100円" String s2 = "Hello, ".concat("World"); // → "Hello, World"

String.format%s (文字列) や %d (整数) のような書式指定子で穴埋めする書き方で、C 言語printf を知っている人にはおなじみです。複雑な書式 (桁揃え、小数点以下の桁数) を扱うときに便利です。String.concat は文字列専用の連結メソッドで、+ よりも厳密 (引数が String でないとコンパイルエラー) です。

詳細は後のレッスンで扱いますが、ループの中で大量の文字列を組み立てるときは + ではなく StringBuilder を使う、というベストプラクティスもあります。これも今は「そういうのがあるんだ」程度に覚えておけば十分です。

1 + "" + 21 + 2 + "" は別物

文字列連結でいちばん面白いのが、評価順序の話です。次の 2 つの式の結果を、まず予想してみてください。

Java

String a = 1 + "" + 2; // ? String b = 1 + 2 + ""; // ?

結果は a = "12"b = "3" です。同じ要素を使っているのに、順番で結果がガラリと変わります。理由を順番に追ってみましょう。

a = 1 + "" + 2 の評価では、まず左から 1 + "" が計算されます。左が int1、右が String"" なので、結果は文字列連結になって "1" が生まれます。続いて "1" + 2 を計算するので、これも文字列連結になって "12" です。

一方 b = 1 + 2 + "" の評価では、まず左から 1 + 2 が計算されます。両方とも int なので、これは普通の足し算で 3 です。続いて 3 + "" を計算するので、ここで初めて文字列連結が発動して "3" になります。

diagram (will load when visible)

+ は左から右へ順番に評価される、というルールを覚えておくと、この罠を避けられます。String が登場した瞬間から、それ以降の + はすべて文字列連結になる、と考えるとわかりやすいです。

途中で文字列の足し算と数値の足し算を混在させたいときは、カッコで括って意図を明示するのが鉄則です。"合計: " + (a + b) のように書けば、(a + b) が先に数値として足し算され、その後で文字列と連結されます。これは前のレッスンの優先順位の話と同じで、Java でも「迷ったらカッコ」が安全です。

よくある間違い

文字列連結まわりで初心者がやらかすミスは、おおむね次の 3 つに集約されます。

  • 数値同士を連結したつもりが足し算になる"合計: " + a + b と書くと、a + b が最初に連結されてしまい、a = 1, b = 2 の場合 "合計: 12" になります。"合計: " + (a + b) のようにカッコで括れば "合計: 3" になります
  • 評価順序を勘違いする1 + 2 + "円""3円" ですが、"金額: " + 1 + 2"金額: 12" です。String が登場した瞬間から、以降の + は文字列連結になります
  • null を連結すると "null" になるString name = null; String msg = "こんにちは、" + name; と書くと、msg"こんにちは、null" という文字列になります。意図せず null を含んだ表示が出てしまい、ユーザーに気付かれて慌てる、というのは Java の現場でよくある失敗です。事前に if (name != null) でチェックするか、Objects.toString(name, "匿名") のようにデフォルト値を用意しましょう

もうひとつ、地味だけど多いのが、半角スペースの忘れです。"商品名:" + item と書くと "商品名:ペン" のように : の後ろにスペースが入らず、見た目が窮屈になります。"商品名: " + item のように、: の後ろに半角スペースを入れる癖を最初から付けておきましょう。

文字列連結のバグは「動くけれども結果が想定と違う」という形で出てきます。ArithmeticException のような派手なエラーで止まってくれないので、テストで実際の出力と期待値を文字単位で見比べる癖を付けてください。スペース 1 つ、カンマ 1 つで結果は別物になります。

やってみよう

それでは課題に挑戦してみましょう。今回のメソッドは formatPrice(String item, int price) です。

  1. 右側のエディタを開く
  2. return "商品名: " + item + ", 価格: " + price + "円"; のような形で、+ を使って 4 つのパーツを連結する
  3. "商品名: ": の後ろの半角スペース、", 価格: " のカンマと半角スペース、"円" の前にはスペースなし、を丁寧に確認する
  4. 「実行」ボタンを押して、テストが緑になることを確認する

コツは「文字列と数値を + で連結すると、数値が自動で文字列になる」ことを思い出すことです。今回は priceint なので、String.valueOf(price) のような変換は不要です。+ の隣に String を置けば、勝手に文字列化されて連結されます。

慣れてきたら、自分で "在庫: " + true"円周率: " + 3.14 のような式を試してみたり、String.format を使った別解を書いてみたり、自由に遊んでみてください。文字列の組み立てが自由になると、ログ出力やデバッグ、API のレスポンス整形など、実務でも一気にコードが書きやすくなります。

次のレッスンでは、ここで学んだ文字列連結と算術演算を組み合わせて、もう少し実用的なコードに挑戦していきます。

よくある質問

Q. Java と他言語の文法はどう違いますか?

A. Java は静的型付けで、変数宣言時に型を明示します(int x = 0;)。中括弧でブロックを表し、文末にセミコロンが必要です。Python の動的型付けや JavaScript の柔軟さに慣れていると最初は窮屈ですが、コンパイル時にバグが発見できる安全性がメリットです。

Q. コードが動かないときに最初に見るべき場所は?

A. コンパイルエラーは行番号とエラー種別(cannot find symbol、incompatible types など)が表示されます。実行時例外はスタックトレースの最初の at ... が原因行です。IDE(IntelliJ / VS Code)の警告も丁寧に潰すと、半分のバグは未然に防げます。

Q. Java の習得後に学ぶべき技術は何ですか?

A. 基本構文を抑えたら java-intermediate(コレクション / ジェネリクス / Stream / 例外)に進み、Spring Boot や Web 開発に展開するのが王道です。クラウド時代は Kotlin / Scala への展開も視野に入りますが、まずは Java 標準を固めるのが効率的です。

次のレッスン

次は 型変換 (キャスト) で、Java+ 演算子で文字列同士、文字列と数値、boolean を繋げる方法と、評価順序の罠を学ぼう を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 文字列連結 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 文字列連結 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. クラス名は Solution、メソッド名は formatPrice、引数は String item, int price の 2 つ、戻り値の型は String にすること
  2. 出力フォーマットは "商品名: " + item + ", 価格: " + price + "円" の形 (: の後ろは半角スペース 1 個、, の後ろも半角スペース 1 個、 の前にはスペースなし)
  3. + 演算子による文字列連結を使い、String.formatStringBuilder は使わないこと

入出力例

test-cases.txt

formatPrice("ペン", 100)"商品名: ペン, 価格: 100円" formatPrice("ノート", 350)"商品名: ノート, 価格: 350円" formatPrice("ティッシュ", 200)"商品名: ティッシュ, 価格: 200円" formatPrice("サンプル", 0)"商品名: サンプル, 価格: 0円"

ヒント

main.java
main.java
学習モード

メモ

文字列の連結

⌘S で保存