Code Fix

中級

Stringが不変であることの実害

メソッドは新しい文字列を返すだけです。戻り値を捨てるミスと、StringBuilderの使いどころを扱います。

なぜエラーが出ないのか

出力: java
(エラーなし)
javacは何も報告しません。文法として正しいためです
出力: java
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  public class Main {
 2      public static void main(String[] args) {
 3          String s = "java";
 4                 s.toUpperCase();
               ^
 5          System.out.println(s);
 6      }
 7  }
出力: java期待: JAVA (コンパイルは通っています)

Stringは不変です。toUpperCaseは新しい文字列を返すだけで、元の変数は変わりません。

直し方: (空)s = にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  public class Main {
 2      public static void main(String[] args) {
 3          String s = "a,b,c";
 4          System.out.println(s.replace(",", "-")         );
                                                      ^
 5      }
 6  }
出力: a-b-c(replaceの戻り値を使えば正しく動きます)

replaceも新しい文字列を返します。戻り値を使わなければ何も起きません。

直し方: (空)(空) にします。

この問題を解いてみる →

パターン3

 1  public class Main {
 2      public static void main(String[] args) {
 3          String         sb = new StringBuilder();
                   ^
 4          for (int i = 0; i < 3; i++) sb.append(i);
 5          System.out.println(sb);
 6      }
 7  }
Main.java:3: error: incompatible types: StringBuilder cannot be converted to String

ループで文字列を組み立てるならStringBuilderです。String連結は毎回新しい実体を作るため遅くなります。

直し方: StringStringBuilder にします。

この問題を解いてみる →

よくある誤解

「変数の中身を書き換えている」わけではありません。新しい文字列を作って、参照を差し替えているだけです。

まとめ

Stringが不変であることの実害は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)