はじめに
Javaで文字列から特定位置の1文字を取り出すなら、StringクラスのcharAtメソッドを使います。インデックスは0始まりで、戻り値はcharです。そのため、初心者が最初に押さえるべき使い方は、範囲を確認してからcharAt(index)を呼ぶ流れになります。
この完全ガイドでは、基本のサンプルコードから検索、カウント、置換、カスタマイズまでを同じ考え方で整理するのが一般的です。公式ドキュメントによれば、String.charAt(int)は指定位置のchar値を返し、範囲外なら例外を送出します。一方、文字の判定にはCharacterクラスの各メソッドを組み合わせるのが一般的です。
- Java SE 21 / JDK 21
- 標準ライブラリ:
java.lang.String、java.lang.Character、java.util.ArrayList
charAtメソッドの基本構文と戻り値- インデックスを使った安全な文字取得の使い方
- ループ、判定、置換に広げるサンプルコード
- 例外を避ける注意点と範囲チェック
- 複数文字列や部分抽出に応用するカスタマイズ
| 用途 | 主なコード | 型 | 注意点 |
|---|---|---|---|
| 1文字取得 | str.charAt(0) | char | 0始まり |
| 長さ確認 | str.length() | int | 上限はlength() - 1 |
| 数字判定 | Character.isDigit(ch) | boolean | Unicode上の数字も対象 |
| 大文字判定 | Character.isUpperCase(ch) | boolean | 英字以外も考慮 |
| 小文字化 | Character.toLowerCase(ch) | char | 比較前の正規化 |
| 追加構築 | StringBuilder.append(ch) | StringBuilder | 反復連結に向く |
| 範囲確認 | index >= 0 && index < str.length() | boolean | 例外対策 |
| 位置保存 | ArrayList<Integer> | List | importが必要 |
JavaのcharAtメソッドとは
charAtメソッドは、JavaのStringから指定したインデックス位置のcharを取得するAPIです。結論として、文字列を文字の並びとして1文字ずつ扱いたい場面では、length()で範囲を把握し、charAt()で取り出す流れが読みやすくなります。ただし、絵文字など一部の文字はchar一つで表せない場合があるため、Unicodeを厳密に扱う処理ではcodePointAt()も検討します。
結果: 期待される結果は、指定した位置にある1文字がchar型のresultに入る形です。
charAtメソッドの基本
これが基本構文で、文字列にはString型の変数や文字列リテラルを置けますが、覚えておくと役立つでしょう。その位置を表すインデックスはintとして扱われ、最初の文字が0、2番目の文字が1になります。初心者がつまずきやすいのは、人間が数える1文字目とプログラム上の0番目がずれる点です。
そのため、"Hello, World!"に対するcharAt(0)はHを返し、charAt(7)はWを返します。charは単一のUTF-16コードユニットを表す型なので、戻り値を文字列として連結したい場合はString.valueOf(result)やStringBuilderを使うと整理できるのが現実的です。Javaの文字列処理では、この小さな単位を理解してから応用へ進むほうが扱いやすいです。
具体的には、名前の頭文字を取り出す、入力値の先頭記号を判定する、固定桁コードの一部を読む、といった処理でcharAtがよく使われます。一方、部分文字列そのものが必要ならsubstring()、文字の位置を検索したいだけならindexOf()が適する場面もあります。関連する文字列操作はJavaエスケープ処理の記事やJava List型の記事と合わせて読むと、扱う型の違いを整理しやすくなるのが基本です。
💡 Tips:charAtは1文字を読むメソッドです。文字列の一部をまとめて切り出す使い方なら、substring()との役割分担を意識するとコードの意図が伝わりやすくなると整理できます。
基本的に、Stringは不変のオブジェクトとして扱われます。charAtで得た文字を加工しても元の文字列は変わらないため、変換後の内容を残したい場合は新しいStringBuilderや別のStringを用意します。この性質を理解しておくと、置換や抽出のサンプルコードで新しい変数を作る理由が自然に読めるのが目安です。
charAtメソッドの使い方
基本の使い方は、対象のString、取得したいindex、受け取るchar変数をそろえるだけです。ただし、サンプルコードを読むときは、System.out.println()で何を表示しているかよりも、どの位置の文字を取り出しているかを追うほうが理解しやすくなると理解できます。Javaの学習初期では、main()の中に短い処理を書き、動きの対応関係を確認する形が適しています。
サンプルコード1:基本的な使用方法
これから扱う最初のサンプルコードは、文字列"Hello, World!"の先頭文字を取り出す例です。charAt(0)という指定により、Stringの0番目にある文字だけがresultへ入ります。そのため、charAt メソッドの使い方を最短で確認できると覚えるとよいでしょう。
結果: 期待される出力は「取得した文字: H」です。
このコードでは、strに入れた文字列からcharAt(0)で先頭のHを読みます。取得した文字はchar型のresultに格納され、+演算子で表示用の文字列に連結されます。初心者は0が先頭を表す点を覚えると、以後のサンプルコードも読みやすくなるのがポイントです。
サンプルコード2:文字列から特定の位置の文字を取得
その応用として、任意の位置にある文字を取り出す場合も構文は変わりません。"Hello, World!"ではカンマや空白も1文字として数えるため、Wはインデックス7になると考えられます。この数え方を誤ると、意図しない文字を取得しやすくなります。
結果: 期待される出力は「取得した文字: W」です。
このJavaコードでは、charAt(7)で8文字目に相当するWを取得します。charAtメソッド自体は範囲内の位置を読むだけなので、空白や記号も通常の文字として数える点が注意点です。入力値に余分な空白が混ざる場合は、事前にtrim()やstrip()の利用を検討できます。
サンプルコード3:ループを使った文字の取得
これを文字列全体に広げると、for文とlength()を組み合わせて各文字を順番に読めると言えるでしょう。ループの条件はi < lengthにし、最後のインデックスがlength - 1になるようにします。Javaで1文字ずつ検査する処理の土台になる使い方です。
結果: 期待される出力は、インデックス0から3までの文字が1行ずつ表示される形です。
このサンプルコードでは、str.length()で文字列の長さを取得し、iを0から順に増やします。ループ内のstr.charAt(i)が現在位置の文字を返すため、文字列をJ、a、v、aに分解して扱えます。配列の添字に慣れている場合は、同じ感覚で読み進められますし、ここがポイントです。
結果: 期待される出力例は、各インデックスと対応する文字が順番に並ぶ形です。
その出力例から、length()が文字数を返し、charAt(i)が位置ごとの文字を返す関係を確認できるのが基本です。Javaの繰り返し処理では、終了条件をi < str.length()にする書き方もよく使われます。一方、同じ長さを何度も参照したくない場合は、例のようにlengthへ一度代入しておくと意図が明確です。
実際、for文の初期化、条件、更新の位置を見れば、charAtがどの順番で呼ばれるかを追跡できます。i++なら前から後ろへ進み、i--なら後ろから前へ進みますし、ここを基本と考えるとよいでしょう。この違いが、後半で扱う逆順表示や範囲抽出の読み方につながりますが、これは押さえたい点です。
charAtメソッドの応用例
基本が理解できると、charAtメソッドは判定、集計、変換、比較といった処理へ広げられます。どの応用でも中心になるのは、forで1文字ずつ読み、条件に合う文字だけをifで処理する流れです。そのため、サンプルコードごとの差分は、どんな条件で何をするかに集中して読むと整理できます。
サンプルコード4:文字列内の数字のみを取り出す
これらの応用例の中で、数字だけを取り出す処理は入力チェックにもつながりますし、ここがポイントです。Character.isDigit(ch)で文字が数字かどうかを判定し、条件に合った文字だけをStringBuilderへ追加します。サンプルコードとして、英字を含む文字列から数字部分だけを集めますし、これが一つの目安です。
結果: 期待される出力は「取り出した数字: 123456」です。
このJavaコードでは、StringBuilderのappend()で数字だけを順番に蓄積します。charAtで取得したchをCharacter.isDigit()へ渡すため、判定と抽出の役割が分かれます。初心者は、文字を読む処理と条件を判定する処理を分けて考えると理解しやすいです。
サンプルコード5:特定の文字が何回現れるかカウント
その判定を集計に変えると、特定の文字が何回出てくるかを数えられますが、これは押さえたい点です。対象文字をtargetに入れ、各位置の文字chと==で比較します。一致したときだけcount++を実行するため、処理の流れは単純です。
結果: 期待される出力は「文字’a’の出現回数: 3」です。
このサンプルコードでは、bananaの中にあるaを見つけるたびにcountが増えます。char同士の比較ではequals()ではなく==を使えるため、文字列比較よりも軽い記述になります。一方、複数文字の語句を探す場合はcontains()やindexOf()のほうが自然です。
サンプルコード6:文字列の逆順表示
逆順表示では、インデックスを末尾から先頭へ動かするのが目安です。最後の文字はstr.length() - 1にあるため、ループ変数iをそこから始め、i--で減らしていきます。取り出した文字をStringBuilderへ追加すれば、新しい順序の文字列を作れますが、覚えておくと役立つでしょう。
結果: 期待される出力は「逆順の文字列: avaJ」です。
この処理では、len - 1から始める点が注意点です。lenそのものをcharAtに渡すと範囲外になるため、最後の有効インデックスは常にlength() - 1と覚えるとよいです。文字列の並び替えや簡易的な回文チェックにも近い考え方を使えます。
サンプルコード7:アルファベットの大文字・小文字の変換
同様に、1文字ずつ読めるなら大文字と小文字の変換も組み立てられます。Character.isUpperCase()で大文字かを判定し、Character.toLowerCase()またはCharacter.toUpperCase()で反対側に変換するのがポイントです。英字以外が含まれる可能性がある場合は、変換後の文字が期待どおりかを仕様に合わせて確認するのが一般的です。
結果: 期待される出力は「大文字・小文字変換後の文字列: jAVA」です。
このコードでは、Jは小文字へ、a、v、aは大文字へ変わります。Characterクラスのメソッドを使うと、判定と変換をchar単位で書けるため、charAtとの相性がよいです。大文字小文字を含む比較は、Javaアノテーションの記事のような構文理解と合わせ、型と記法を分けて整理すると読みやすくなります。
サンプルコード8:特定の文字の位置をすべて取得
一方、回数だけでなく位置も必要な場合は、見つけたインデックスをArrayListへ保存するのが一般的です。ArrayList<Integer>を使う場合、通常はimport java.util.ArrayList;をファイル先頭に置きます。以下のサンプルコードは元の構造を保つため本文中に補足しますが、実ファイルではimportを追加してください。
結果: import java.util.ArrayList;を補った場合、期待される出力は「aが現れた位置: [1, 3, 5]」です。
このJavaコードでは、positions.add(i)によって一致した位置だけがリストへ入ります。bananaではaがインデックス1、3、5にあるため、結果は[1, 3, 5]になります。Listの扱いはJava List型完全ガイドの内容とつながりますし、ここを基本と考えるとよいでしょう。
サンプルコード9:文字列の比較
文字列全体の比較には通常equals()やequalsIgnoreCase()を使いますが、学習目的ではcharAtで1文字ずつ比べると仕組みが見えるのが現実的です。長さが異なる場合は等しくないため、先にlength()を比較します。その後、各文字を小文字化してから比べれば、大文字小文字を無視した判定になるのが現実的です。
結果: 期待される出力は「文字列は等しい」です。
このサンプルコードでは、str1.charAt(i)とstr2.charAt(i)を同じ位置で読み、Character.toLowerCase()で比較条件をそろえます。breakは不一致が見つかった時点でループを終える役割です。ただし、単純な大文字小文字無視の比較にはequalsIgnoreCase()が現実的です。
サンプルコード10:文字の置換
文字の置換も、対象文字と一致した場合だけ別の文字を追加する形で書けます。Stringは不変なので、元の文字列を直接書き換えるのではなく、StringBuilderで新しい文字列を作りますし、これが一つの目安です。Javaのreplace()でも同様の目的を達成できますが、charAtを使うと条件分岐を細かくカスタマイズできると整理できます。
結果: 期待される出力は「置換後の文字列: Apple」です。
このコードでは、oldCharと一致するaだけをnewCharのAに置き換えます。一致しない文字はそのままnewStr.append(ch)で追加されるため、p、p、l、eは保持されます。条件を増やせば、複数文字の変換や許可文字だけを残すカスタマイズにもつながりますし、ここがポイントです。
具体的には、英数字だけを残す、ハイフンを削除する、先頭だけ大文字に変えるといった加工も同じ流れで作れますが、覚えておくと役立つでしょう。Character.isLetterOrDigit()、Character.isWhitespace()、Character.toTitleCase()などを組み合わせると、入力値の整形ルールをコードへ落とし込みやすくなります。この考え方を押さえると、サンプルコードを自分の要件へ置き換える作業が進めやすくなると理解できます。
注意点と対処法
charAtメソッドの注意点は、インデックスが範囲外になるとStringIndexOutOfBoundsExceptionが発生することです。範囲は0以上、かつstr.length()より小さい値に限られますし、ここを基本と考えるとよいでしょう。そのため、外部入力や計算結果をインデックスに使う場合は、呼び出し前に条件式で守る書き方が安定します。
charAtの範囲外アクセスは、戻り値で失敗を知らせるのではなく例外で失敗します。初心者向けのサンプルコードでも、入力値が変わる処理では範囲チェックを省かないほうが安全です。インデックスが文字列の長さ以上の場合
これが典型的な範囲外アクセスです。文字列"hello"の長さは5なので、有効なインデックスは0から4までになると整理できます。10を渡すと存在しない位置を読もうとするため、例外処理が必要になります。
結果: 期待される出力は「指定したインデックスが文字列の長さを超えていると理解できます。」です。
この例では、tryブロック内で例外が発生し、catchブロックがメッセージを出します。ただし、例外で通常の分岐を表すより、事前にindex < str.length()を確認するほうが意図を読み取りやすくなります。例外処理は、想定外の入力を受けた場合の保険として置く考え方が一般的です。
負のインデックスを指定した場合
一方、負のインデックスも有効範囲に含まれません。JavaのStringでは、Pythonのように-1で末尾を表す使い方はできません。末尾の文字を取りたい場合は、str.charAt(str.length() - 1)と書きますし、ここがポイントです。
結果: 期待される出力は「負のインデックスは指定できません。」です。
このサンプルコードでは、-1を渡した時点で範囲外となります。catchで補足しているためメッセージを出せますが、入力チェックとしてはindex >= 0を先に評価する書き方が適しています。末尾から数えたい要件がある場合は、指定値をstr.length() + indexのように変換する設計も考えられますが、これは押さえたい点です。
対処法:インデックスの範囲を確認する
その対処法として、charAtを呼ぶ前にindex >= 0 && index < str.length()を判定すると覚えるとよいでしょう。条件が真の場合だけ文字を取得すれば、範囲外アクセスを避けられます。初心者向けの完全ガイドとして特に押さえたいのは、この条件式を毎回の癖にすることです。
結果: 期待される出力は「指定したインデックスの文字は: v」です。
このコードでは、indexが2なので、3文字目にあたるvを取得します。条件式の左側で負の値を除外し、右側で長さ以上の値を除外しているため、charAt(index)を安全に呼べます。入力値の検証という観点では、Javaでうるう年を判定する記事の条件分岐も参考になると覚えるとよいでしょう。
ただし、Unicodeの補助文字を含む文字列では、charAtが返すcharとユーザーが見ている1文字が一致しない場合があると考えられます。たとえば一部の絵文字はサロゲートペアとして扱われ、charAtでは片側のコードユニットだけを読む可能性があります。その場合はcodePointAt()、codePoints()、offsetByCodePoints()などを使う設計が向いていると考えられます。
その違いは、ログ解析や固定長コードの処理では問題になりにくい一方、ユーザー名やメッセージ本文を1文字単位で扱う処理では表面化しやすくなると言えるでしょう。仕様としてユーザーが見る文字を単位にするなら、charではなくコードポイント単位の処理を検討します。API選択の注意点を最初に決めておくと、後から文字化けや欠落を追う負担を減らせますし、これが一つの目安です。
カスタマイズ方法
charAtメソッドのカスタマイズは、読み取った1文字をどのように使うかで決まります。複数の文字列を同じ位置で読む、見つけた位置を一覧化する、範囲内の文字だけを新しい文字列にする、といった処理は同じ基礎から作れますが、これは押さえたい点です。カスタマイズの幅を広げるには、配列、拡張for文、StringBuilderを合わせて理解するとよいです。
複数の文字列から特定の位置の文字を一括で取得
これにより、複数の単語から同じ位置の文字をまとめて取得できます。例ではString[]の各要素から先頭文字を取り出し、for (String word : words)で順番に処理します。すべての文字列に対象インデックスが存在する前提で書かれている点は注意点です。
結果: 期待される出力は、a、b、cが順に1行ずつ表示される形です。
このサンプルコードでは、配列words内の各Stringに対してcharAt(0)を適用します。すべての単語が1文字以上あるため問題なく動く想定ですが、空文字列が混ざる可能性があるならword.length() > 0を確認します。こうした配列処理は、Javaのオーバーライド記事で扱うメソッド設計とも関係すると言えるでしょう。
特定の文字が出現するすべての位置を取得
同様に、位置を出力するだけならリストへ保存せず、その場でSystem.out.println()できるのが基本です。保存が不要な処理では、変数を増やさないほうが読みやすくなります。一方、後続処理で位置一覧を使うならArrayListに格納するほうが適しているのが基本です。
結果: 期待される出力は「文字 g が出現する位置: 3」と「文字 g が出現する位置: 10」です。
このコードでは、programmingの各文字を読み、gと一致した位置だけを出力します。str.charAt(i) == targetという条件が真になったときにだけ表示されるため、余分なデータ構造を使わずに目的を達成できます。検索結果を画面に出すだけの小さな処理なら、この使い方が簡潔です。
任意のインデックス間の文字列を抽出
ところで、指定範囲の文字列を得るだけならsubstring()が自然です。あえてcharAtとStringBuilderを組み合わせると、範囲内の文字を加工しながら抽出できるのが目安です。サンプルコードでは、インデックス1以上5未満の文字を順に追加します。
結果: 期待される出力は「抽出した文字列:ello」です。
このコードでは、iが1、2、3、4の間だけ動くため、HelloWorldからelloが作られます。sb.toString()でStringBuilderをStringへ戻す点も確認しておきたい使い方です。途中でCharacter.toUpperCase()を挟めば大文字化しながら抽出でき、条件を加えれば数字だけを残すカスタマイズにもなります。
substring()、1文字ずつ判定や変換を入れるならcharAtとStringBuilderの組み合わせが向いているのがポイントです。使い分けると、コードレビュー時にも意図が伝わりやすくなります。範囲をそのまま抜き出すだけの処理にfor文を書くと、後から読む人は何らかの加工があるのかと考えます。一方、文字ごとの判定や変換が含まれるなら、charAtを使った明示的なループが処理内容を表しやすくなるのが目安です。
まとめ
JavaのcharAtメソッドは、Stringから指定位置のcharを取得するための小さなAPIです。使い方の核は、0始まりのインデックスを理解し、length()で有効範囲を確認してから呼び出すことにあるのが一般的です。この流れを守れば、初心者でも例外を避けながら文字列処理を書きやすくなります。
その基礎は、数字だけの抽出、文字のカウント、逆順表示、大文字小文字の変換、位置の取得、置換などへ広がります。どのサンプルコードでも、forで位置を動かし、charAt(i)で文字を読み、ifで条件を分けるという構造は共通です。そのため、一つの例を暗記するより、共通する読み方を身につけるほうが応用しやすくなるのが現実的です。
ただし、StringIndexOutOfBoundsExceptionを避ける範囲チェックと、charがUTF-16コードユニットである点は継続して意識する必要があります。通常の英数字や日本語の一部を扱う処理ではcharAtで足りる場面が多い一方、絵文字や補助文字を厳密に扱う処理ではcodePointAt()などを選ぶ判断も必要です。完全ガイドとしての結論は、単純な1文字取得にはcharAt、範囲抽出にはsubstring()、Unicode単位の厳密処理にはコードポイント系APIを使い分けることです。
これらの注意点を踏まえると、charAtは短い構文でありながら、文字列処理の基礎を理解する入口になります。サンプルコードを自分の入力値へ置き換えるときは、対象文字列、インデックス、範囲チェック、戻り値の使い道を順に確認すると整理できます。その順序で読めば、エラーの原因も処理の意図も追いやすくなるのがポイントです。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


