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連結は毎回新しい実体を作るため遅くなります。
直し方: String を StringBuilder にします。
よくある誤解
「変数の中身を書き換えている」わけではありません。新しい文字列を作って、参照を差し替えているだけです。
まとめ
Stringが不変であることの実害は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。