1. HOME »
  2. Java Tips »
  3. Beginners

Beginners Article

ソーシャルブックマークに登録 : Yahoo!ブックマークに登録 はてなブックマークに登録 del.icio.usに登録 newsing it!に登録 Buzzurlにブックマーク livedoorクリップに登録 Choix!にブックマーク イザ!ブックマーク

print 印刷用ページの表示

Javaにおける文字/文字列の扱い方

Unicodeの基本、そしてJavaにおける文字/文字列の操作方法を理解する

Javaプログラムを開発するうえで、文字列の扱い方に関する知識は必須です。そこで本稿では、Javaにおける文字と文字列の扱い方について説明します。なお、Javaでプログラムを書く場合、文字コードにはUnicodeを使用すると決まっているので、文字と文字列の説明の前に、まずUnicodeについても簡単に説明しておきます。

2005年2月14日更新

text ●  青柳龍也 津田塾大学情報科学科 http://cs.tsuda.ac.jp/

※ 本文中にバックスラッシュが登場しますが、Windows上ではバックスラッシュが円マークで表示されます。そのため、記事では一部バックスラッシュ部分を便宜的に「☆」に置き換えています。☆部分は適宜、バックスラッシュに読み変えてください。

Unicodeの基礎知識

 Javaのプログラムは、Unicodeで記述することになっています。これは、Javaの言語仕様で決められています。Unicodeは、「Unicode Consortium」が策定している文字コードで、世界中で使われているさまざまな文字を、16ビット単位のUnicode文字で表そうという規格です。

 Unicode ConsortiumのWebページには、以下のようなキャッチフレーズが載っています。

Unicode provides a unique number for every character,
(Unicodeは、すべての文字に固有の番号を付与します)
no matter what the platform,
(プラットフォームには依存しません)
no matter what the program,
(プログラムにも依存しません)
no matter what the language.
(言語にも依存しません)

 Unicodeは、16ビットで文字を表現します。16ビットということは、216 = 65536種類の文字を表現できます。実際に何文字が定義されているのかは、Unicodeのバージョンによって異なりますが、Javaで採用されているUnicode 2.1では、約4万字程度の文字が割り当てられています※1

 文字コードに関する議論には、いろいろと奥深いものがありますが、Javaの初心者プログラマーとしては、とりあえず以下のポイントくらいを理解しておけばよいと思います。

●Unicode文字は1文字が16ビット
●最初の128文字はASCIIコードと一致
●コンピュータで通常使っている日本語文字が含まれている

 ASCIIコードでは、1文字を7ビットで表現し、アルファベットや数字、記号、制御文字などを定義していますが、それらは、Unicodeの最初の128文字と一致しています。どの文字が含まれているのかだけでなく、その順番も同じなので、7ビットのASCIIコードに、上位ビットとして0を9個追加して16ビットにすれば、Unicodeでの表現と同じになります。

 例えば、「A」という文字は、ASCIIコードでは7ビットで「100 0001」と表しますが、この上位に0を9個追加して、「0000 0000 0100 0001」とすれば、Unicodeの「A」になります。

 私たちがコンピュータで通常使っている日本語の文字は、主に「JIS X 0208-1990」という規格で定められたものですが、それらはすべてUnicodeに含まれています。ただし、ASCIIコードの場合と違って、順番までは一致していないので、単純な方法で変換することはできません。変換したい場合には、対応表を使って変換することになります。

※1 Java言語仕様書の「3.1 Unicode」によると、Javaの処理系で使われているUnicodeのバージョンは、表Aのようになっている。なお、Unicodeの最新バージョンは3.1.1である。

表A:JDKのバージョンとUnicodeのバージョンの対応

Unicode以外で記述したプログラムのコンパイル

 Unicodeもだいぶ普及してきましたが、多くの環境では、現在でもほかの文字コードが使われています。例えば、日本語版Windowsでは、通常、シフトJISが使われています。
 先に述べたように、Javaのプログラムは、Unicodeで記述することになっていますが、Unicode以外の文字コードが扱われる環境でソース・プログラムを作成した場合のために、以下のような2つの仕組みが用意されています。

●Unicodeエスケープ
●エンコーディング変換


 Unicodeエスケープとは☆uの後ろに16進4ケタでUnicodeのコード番号を書く方法です(後述する理由から、Windows上ではバックスラッシュが円マークで表示されます)。例えば、Unicodeの「は」のコード番号は、16進で306fです。これをUnicodeエスケープでは、

☆u306f

と書きます。306fの部分は、大文字を使って、

☆u306F

とすることもできます。

 Unicodeエスケープを使うと、ASCIIコードだけで、すべてのUnicode文字を表現することができます。とはいえ、Unicodeエスケープだけでさまざまな文字を扱おうとするのは大変です。そこで、もう1つのサポートとして、エンコーディング変換が用意されているのです。

 エンコーディング変換を利用するには、javacコマンドを実行する際に、-encodingというオプションを使って、ソース・ファイルの記述に使ったエンコーディング方法を指定します。例えば、ソース・ファイルを記述するのにシフトJIS(SJIS)を使った場合には、「-encoding SJIS」というオプションを指定します。すると、コンパイルの前に、シフトJISからUnicodeへの変換が行われ、その後、コンパイルが行われるという仕組みです。

 また、-encodingを指定しなかった場合には、そのコンピュータのデフォルトのエンコーディング方法が選択されます。例えば、日本語版Windowsでは、シフトJIS(正確にはMS932)というエンコーディング方法が使われているものと仮定されます※2。要するに、そのコンピュータで“普通に”ファイルを作ると、自動的にUnicodeに変換されたうえでコンパイルが行われるというわけです。

 エンコーディング変換を行う場合にも、Unicodeエスケープの処理は、エンコーディング変換を行わない場合と同じように行われます。つまり、Unicode以外で記述したJavaのソース・プログラムをjavacでコンパイルすると、図1のような2段階の処理が行われることになります。

図1:javacの処理

「u」が2個以上あってもよい理由

 実は、Unicodeエスケープの☆uのuは、2個以上記述してもよいことになっている。例えば、「あ」はUnicodeで3042であるが、Unicodeエスケープによって☆u3042と書いても、☆uuuuu3042と書いても「あ」に変換される。

 何のために、このようなルールになっているのだろうか。Java言語仕様書の「3.3 Unicode Escapes」によると、「JavaプログラムをASCIIコードに変換する標準的な方法を提供するため」となっている。

 例えば、Unicodeで記述されたプログラムの中に、以下のような部分があったとする。

☆3042 あ

 Unicodeエスケープを使って、「あ」の部分を単純にASCIIコードに変換すると、以下のようになる。

☆3042 ☆3042

 このようにしてしまうと、元のプログラムで「\u3042」だったのか、それとも「あ」だったのか区別がつかなくなり、元に戻そうとしても、

☆u3042 あ

には戻せなくなる。

 そこで、仕様書では、この例の場合であれば、以下のようにするのがASCIIコードに変換するための標準的な方法だとしている。

☆uu3042 ☆u3042

 つまり、Unicodeエスケープにはuを1個追加し、Unicode文字のほうはuが1個のUnicodeエスケープにする。こうすれば、uの個数によって、元のプログラムではUnicodeエスケープだったのか、それともUnicode文字だったのかを区別することができる。元に戻す場合には、uが2個以上ならuを1個減らし、uが1個ならUnicode文字に戻せばよい。

 uがいくつ続いてもよいという仕様なので、ASCIIコードに変換後の

☆uu3042 ☆u3042

も、もちろん正しいプログラムとして扱われる。

ページの先頭へ戻る