(1/4)本連載は、Java言語やその文法は一通り理解しているが、「プログラマー」としては初心者、という方を対象とします。Javaコアパッケージを掘り下げることにより「プログラマーの常識」を身に付けられるように話を進めていきます。今回は、文字コードや文字化けについて。Eclipseではじめるプログラミング」をご参照ください。今回は、文字コードや文字化けなどの文字に関する常識をJavaを通して身に付けていきます。私たちプログラマーにとって、文字や文字列を扱うことはとてもありふれたことです。ほとんどのプログラムにおいて、何らかの形で文字や文字列を扱っていることでしょう。インターネット時代には必須の知識コンピュータ1台で動作するプログラムを扱っている範囲では、皆さんは特に何の困難に出合うこともなく文字や文字列を扱っておられるかもしれません。ところが、ファイルやネットワークを経由したほかのコンピュータとのデータ交換を取り扱い始めた途端、文字コードや文字化けといったキーワードがあなたの前に立ちはだかる場合があります。文字コードや文字化けといったものはある程度経験を持ったプログラマーにとっても難易度の高いもののひとつです。インターネットが普及してネットワークを経由したコンピュータ利用などが常識化した現代においては、文字コードや文字化けといった知識はプログラマーに常識として求められるようになってきたものと考えられます。この記事では、文字コードや文字化けといったものについての全体像をお伝えすることを目標とします。あなたが文字コードや文字化けで困ったときの道しるべとなる、いくつかの情報源を示します。「文字化け」は科学的な現象であるある文字を表すデータが入力され、コンピュータ上のデータ処理やデータ表示などを経由して最終的に表示/印字などの形で出力された際に、別の文字に見えるように変わってしまった(化けてしまった)という現象は一般に「文字化け」と呼ばれます。「文字化け」は、なんだか「おばけ」みたいな語感ですが、基本的に再現性のある科学的な現象です。「狸」が化けてしまったなお、この記事では特によく現れる文字化けのみを扱います。ハードウェア的な原因や通信品質などといったものに起因する文字化けの話題などは扱いません。私たちがコンピュータ関連の技術を調べていくうえで、一次情報源に立ち戻ることは、とても重要です。国際規格や国家規格として文字コードの一次情報源が提供されています。Standardization)による規格。0208:1997これらの規格は販売されています。文字コードに関連する各種情報源として、以下のものもよく参照する必要が出てきます。RFCこのような文字コードに関するさまざまな規格や標準があるからこそ、そして、それら規格や標準をみんなで守っているからこそ、異なる複数のコンピュータ間で通信などを行うことができます。これらの規格や標準は、文字コードに関連する各種技術に不慣れな人が参照するには、難易度が大変高いものです。正しいものでも、理解できないことには使いこなすことができません。文字コードを学ぶ場合、まずは一般書籍などから接していくことをお勧めします。オススメの参考書籍は、この記事の最後のページで紹介しています。Java言語における文字コード関連の記載Java言語における文字コード関連情報は、以下などに記載があります。▼サポートされているエンコーディング▼java.lang.Characterクラス▼パッケージjava.nio.charsetこのドキュメントに記載があるように、多くのユーザーはjava.nio.charsetパッケージを直接使用することはほとんどありません。その代わりに、java.lang.String、java.io.InputStreamReaderやjava.io.OutputStreamWriterクラスを使用します。‘愛’で学ぶJava言語における文字と文字列ここからは、Java言語に話題を移します。最初に基本に立ち返り、Java言語における文字と文字列とを復習しておきましょう。Java言語では、ほかのいくつかのプログラミング言語と同様に、「文字」と「文字列」は別のものとして実装されています。本来のUnicode仕様に基づく「Unicodeスカラー値」。U+0000〜U+FFFFの文字セットは、「基本多言語面(BMP)」と呼ばれ、この範囲の文字はchar1つが1文字を表す。Java言語における文字と文字列このように、文字と文字列とはJavaでは別のものとして扱われます。相互に変換しながら利用していく場合が多いです。charは文字であるとともに整数でもある一方、連載第3回で説明したように、charはJava言語にとってプリミティブの整数型という側面を持っています。文字を扱うプログラミングを行っていくと、charを数値として処理する場合もありますので、その際にはcharが整数でもあることを思い出してください。文字と文字列との相互変換それでは、実際に文字と文字列との相互変換を中心に見ていきましょう。文字列を文字の配列に変換するところから見ていきます。java.lang.Stringをchar配列に変換するには、toCharArrayメソッドを用います。[愛植岡]を文字に分解。[岡]与えられた文字列が、文字の配列へと分割されていることが確認できます。ここまでは、ごく普通の出力結果ですね。これを掘り下げて、文字(char)の内容を16進表記で見てみます。プログラムを少し変更して、Integer.toHexStringにより16進表記を取得します。"]を文字コードに分解。"]");}}}実行結果は以下のようになります。[愛植岡]を文字コードに分解。[5ca1]ここで表示された611bなどの数値を用いて、今度は文字(char)へと変換できることを確認します。Java言語の文字定数の記法として'\u611b'のような書き方があります。ここで得られた611b、690d、5ca1の値からchar配列を作成し、それから文字列を作ります。{System.out.println("文字の配列から文字列を作成。");}}確かに、元通りの文字列が得られることが確認できます。文字の配列から文字列を作成。配列から作られた文字列は[愛植岡]です。文字エンコーディングとは?文字コードとは、文字を数値で表現するものこのように、Java言語では‘愛’などの文字1つずつが、611bといった数値によって表現されています。この、文字に対応する数値のことを「文字コード」と呼びます。文字と文字コードの対応をひとまとめにしたものを「文字エンコーディング」と呼びます。Java言語では、UTF-16という文字エンコーディングを内部的に採用しています。‘愛’が611bになるのは、UTF-16エンコーディングによるものなのです。世界中のコンピュータで‘愛’の文字コードが常に611bになるのかといえば、そうではありません。いう2バイトの数値で表現されます。ある文字エンコーディングでは、そもそも‘愛’という文字を扱えません。エンコーディングについて考える際には、「どのような文字」が「どのような数値」で表されているかを理解しておく必要があります。符号化文字集合の中にその文字が含まれていれば扱うことができ、含まれていないと扱うことができません。なったり、あるいは別の数値になったりというように、ある文字を表す数値は変化します。文字エンコーディングを調べていくと、規格や標準によって、符号化文字集合と文字符号化方式とを分けて考えたり、あるいは両方をセットで考えたりするものがあります。ここは混乱しやすいポイントの1つですので、ご注意ください。この記事では、符号化文字集合と文字符号化方式の両方を併せて「文字エンコーディング」と呼ぶことにします。「文字コード」という用語は、一般的なコンピュータ関連ドキュメントの前後の文脈によっては「文字エンコーディング」を指している場合があります。「文字コード」の記載が、文字の値を指しているのか、それとも「文字エンコーディング」を指しているのか、読み分けましょう。「世界中の文字にユニークな数値を割り当てたい」という夢のような文字コード標準が、Unicodeです。世界中の文字を、1つの符号化文字集合として取り扱うことができるように、標準化団体が活動しています。その1】:未対応が多い表1に記載したように、ほとんどの場合はchar1個が1文字を表します。char1個が常に1文字を表してくれるのであれば、プログラミングは簡潔になります。ところが、「補助文字」の場合には、char2個が1文字を表すようになっているので、注意が必要です。Pair)と呼びます。サロゲートペアはJava言語そのものにおいて適切にサポートされています。最近のOSでも、サロゲートペアは適切に扱えるようになってきました。サロゲートペアに適切に対応したアプリケーションは原稿執筆時点では少数派である、というのが実情です。フォントについてもサロゲートペア対応のものを利用する必要があります。詳しくは『文字コード超研究』の460ページなどをご覧ください。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。