Code Fix

中級

char の演算と文字コード

charは演算するとintに昇格します。'0'を引く定番テクニックの仕組みも解説します。

なぜエラーが出ないのか

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

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

パターン1

 1  public class Main {
 2      public static void main(String[] args) {
 3          char c = 'a';
 4          System.out.println(c + 1         );
                                      ^
 5      }
 6  }
出力: 98期待: b (コンパイルは通っています)

charは演算するとintに昇格します。文字として出したければcharへ戻すキャストが要ります。

直し方: c + 1 を (char) (c + 1) にします。

この問題を解いてみる →

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

パターン2

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

文字'1'の数値は49です。'0'を引くと文字コードの差が取れて数値の1になります。

直し方: (空) を - '0' にします。

この問題を解いてみる →

パターン3

 1  public class Main {
 2      public static void main(String[] args) {
 3          String s = "java";
 4          for (int i = 0; i < s.length(); i++) {
 5              System.out.print(s.get      (i));
                                       ^
 6          }
 7      }
 8  }
Main.java:5: error: cannot find symbol symbol: method get(int)

1文字取り出すのはcharAt(i)です。Stringにはget(int)というメソッドはありません(Listのgetと混同しやすい箇所です)。

直し方: get を charAt にします。

この問題を解いてみる →

パターン4

 1  public class Main {
 2      public static void main(String[] args) {
 3          char c = '7';
 4          int n = c                           ;
                                  ^
 5          System.out.println(n * 2);
 6      }
 7  }
出力: 110期待: 14 (コンパイルは通っています)

charをそのままintにすると文字コード(55)になります。数字としての値を得るにはCharacter.getNumericValueを使います。

直し方: c を Character.getNumericValue(c) にします。

この問題を解いてみる →

パターン5

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

英字の大文字と小文字は文字コードが32違います。演算結果はintになるのでcharへ戻すキャストが要ります。

直し方: c を (char) (c - 32) にします。

この問題を解いてみる →

よくある誤解

charは数値型です。'a' < 'b' が成り立つのは、文字コードを比較しているからです。

実務での勘所

char c = 'a' + 1;は一見intになるはずなのにコンパイルが通ります。これは'a' + 1が定数式として評価され、値がchar型の範囲に収まると分かっている場合に限りjavacが暗黙に絞り込み変換(narrowing)を許可する特別ルールがあるためです。同じ計算でもchar c = someChar + 1;のようにsomeCharが変数(定数式ではない)だと、この特例は働かずコンパイルエラーになります。「定数式かどうか」で挙動が変わる、地味だが把握しておくと役立つルールです。

演習をはじめる

関連するエラー

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