文字コード

Javaの内部では文字(char)は全てUnicodeで表されており、日本語も含めてほとんどの言語を"自然に"扱うことができます。
これは国際化(多言語対応)されたアプリケーションを開発するときには大きなメリットとなります。

文字列の長さ

既に学習したように文字列長はStringクラスのlength()メソッドで取得することができます。
この文字列長はUnicodeでの文字(char)の数を表す為、全角文字も半角文字も1文字としてカウントしました。
ところが、日本語環境でアプリケーションを開発していると、半角と全角を意識しなくてはならない場合もあります。

バイト数の取得

文字列のバイト数を取得する為には、StringクラスのgetBytes()メソッドを使用します。
このメソッドを使う事で文字列をバイト配列に変換できる為、そのバイト配列のサイズを取得すれば文字列のバイト数が取得できます。

    String str = "Java入門";
    int byteSize = str.getBytes().length;

したがって、このようにして取得したバイト数と文字列のサイズ(Unicodeでの文字数)を比較して、等しい場合には全て半角で記述されていると判断できます。


さて、StringクラスのJavaDocを見てみましょう。

public byte[] getBytes()
 プラットフォームのデフォルト文字セットを使用してこの String をバイトシーケンスに符号化し、結果を新規バイト配列に格納します。

http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/String.html#getBytes()

ここで書かれている「プラットフォームのデフォルト文字セット」とは、いわゆる文字コードの事です。
Javaでは文字は全てUnicodeで表現されますが、Windows環境ではShif_JIS(正確にはCP932)で表現され、Unix環境ではEUC-JPで表現されます。
つまり、プラットフォーム(環境)が異なれば文字列のバイト数が異なる可能性があります。

文字コード

文字コードに関しては最低限は知っておくべきことを示します(正確な情報を知りたい場合は、専門に扱った書籍やWebサイトを探して見てください)。
最初にJavaを使っていく上で耳にするであろう文字コードに関して簡単に説明します。

Unicode

Unicodeユニコード)とはコンピュータ上で多言語の文字を単一の文字コードで取り扱うために1980年代に提唱された文字コードである。

http://ja.wikipedia.org/wiki/Unicode

UniCodeが発明される以前は、コンピュータ上で表現できる文字には限界がありました。
欧米では多くの種類の文字は必要としなかった為(アルファベット+記号)、文字は1バイトで表現できました。
これがいわゆるASCII(アスキー)です(ASCIIはAmerican Standard Code for Information Interchangeの略ですから、ASCIIコードとは呼ばない)。


ところが、全世界の言語、特に漢字などを統一した文字コードで扱う為には1バイトという範囲(256種類)はあまりにも狭かったのです。
コンピュータが欧米諸国のみの技術ではなく第三世界まで進出すると、必然的に他言語対応のアプリケーションの開発は必須となりました。
そこで発明されたのが、1文字を2バイトで表現するUnicodeです(現在は既に2バイトでも足らなくなっており、さらに拡張が行われていますが、現状は2バイト文字として理解して問題ない)。

Shift JIS

Shift_JIS(IANAへの登録名。読み方は『シフトジス』)は、現在多くのパソコン上で日本語を表すために使われている文字コードである。当初はベンダ独自のコード系だったが、現在は標準化されてJIS X 0208の附属書1で規定されている。

http://ja.wikipedia.org/wiki/Shift_JIS

Shift JISは最も馴染みの深い文字コードでしょう。
それもそのはずで、Shft_JISは日本独自で開発された日本語を表現する為の文字コードです。
したがって、アルファベットを表現する(ASCII文字は含む)事は考慮されていましたが、やはり全世界の言語を表現するような設計はされていませんでした。
しかし、この文字コードは互換性の点から現在でも広く使われており、日本語を扱えるPCのほとんどはShift_JISをデフォルトの文字コードとしています。
ただ、現在のWindowsマシンでは厳密にはShift_JISではなくMicrosoftがShit_JISを拡張したCP932という独自に拡張した文字コードが採用されており、問題を複雑しています。

CP932

Microsoftコードページ932(以下CP932)は、マイクロソフト及び、MS-DOSOEMベンダがShift_JISを独自に拡張した文字コードである。また同時に、CP932はShift_JISWindowsアプリケーションにおける「実装」を指す用語であるとも言える。

http://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932

CP932は我々の使用する日本語版Windowsで採用されている文字コードです。
このMS932はShift_JISとほとんど変わりませんが細部が微妙に異なります。
我々が「メールの文字コードはShit_JIS?」というような会話をしている時、厳密にはそれはCP932である事がほとんどです。
つまり、「プラットフォームのデフォルト文字セット」とはWindows環境であればこのCP932を指します。
このCP932と呼ばれる文字コードWindows-31Jとも呼ばれます。


どうしてShit_JISと細部で異なるのか気になる方はリンク先のWikipediaを参照してみてください。
ざっくり言えば、各社の政治的な駆け引きの中で各社の独自実装があったが最終的にMicroSoftが勝ったから、という事です。

EUC

Extended Unix Code(EUC)は、UNIX上でよく使われる文字コードの符号化方式。

http://ja.wikipedia.org/wiki/Extended_Unix_Code

詳細は省きますが、Unix上のデフォルト文字コードで2バイトで1文字を表します。
尚、EUCには日本語に対応したEUC-JP、韓国語に対応したEUC-KRなど幾つかのコードがあり、国内で単純にEUCと言った場合は暗黙的にEUC-JPを指すでしょう。

コード変換

Javaでは内部的にはUnicodeで文字を扱う為、ファイルなどから文字列を入力された場合にUnicodeに変換されます。
Unicodeの文字セットはCP932(Windows-31J)やEUC-JPの文字セットを含む形で定義されている為、通常はCP932やEUC-JPからUnicodeへの変換は容易です。
また、Javaの内部でもCP932(またはEUC-JP)で扱える文字を使っている限りは、それぞれの文字コードに変換することも可能です。
しかし、Windows機種依存文字(○付1など)はEUC-JPには存在しない為、Unix上で実行してEUC-JPとしてテキストファイルを出力しようとすると変換ができなくなります(いわゆる文字化け)。


Windows環境で開発してWindows環境で使うならば問題は起きませんが、開発環境と実行環境の文字コードが異なる場合は充分に注意しなくてはならない問題です。
尚、Javaで扱える文字コードドキュメントで記述されています。
これによれば、CP932(Windows-31J)は「MS932」、EUC-JPは「EUC_JP」という名前で定義されています。
微妙に名称が異なりますが、これはJavaのルールになっている為、正確に使いましょう。

文字コードを指定したバイト配列

文字列からバイト配列を作成する時に、明示的に文字コードを指定するには、getByte()のオーバーロードメソッドを使い、引数に文字コードを表す文字列を渡します。

public byte[] getBytes(String charsetName) throws UnsupportedEncodingException
 指定された文字セットを使用してこの String をバイトシーケンスに符号化し、結果を新規バイト配列に格納します。

http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/api/java/lang/String.html#getBytes(java.lang.String)

ここで指定する文字セットの名前は、ドキュメントで定義されたコード名です。
実際にはエイリアス(別名)が作成されている為、「MS932」ではなく「Windows-31J」を指定することも可能です。
尚、EUC-JP、EUC_JPなどは可能ですが、「Windows_31J」は不可などエイリアスには謎も多い為、ドキュメントで定義された名前を使うのが無難です。

Unicodeの指定

Unicodeでファイルの入出力を行う場合は、Unicodeのバージョンが関連してきます。
通常、日本語環境で使うレベルではUTF-8を使用すれば充分です(この件に関しては事情が複雑でUTF-8以外はほとんど使わない為、今回は割愛します)。