Javaで文字列の文字コードを変換する

String eucjpStr = new String("変換したい文字列".getBytes("EUC_JP"), "EUC_JP");

この例の場合ECU-JPに変換します。変換したい文字列の文字コードは、UTF-8でもShift_JISでも何でも良いです。
たったこれだけの事なんだけど、検索しても全然これだけの事が見つからなくて、無駄に時間費やしちゃって、カッとなって書いた。

愚痴

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

http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/String.html#getBytes(java.nio.charset.Charset)

指定された 文字セット を使用して、指定されたバイト配列を復号化することによって、新しい String を構築します。新しい String の長さは文字セットによって変化するため、バイト配列長と一致しないことがあります。

http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/String.html#String(byte[],%20java.lang.String)

なんとも分かりにくい日本語です。なので、普段Javaを書いてる人が実際に書いたのを見て確認しようと、「Java 文字コード 変換」とかで検索したのに、全然出てこないという。あと、getBytes()に渡す文字コード名が変換前のを指定とか間違ってるページもあったり、とにかくちょっとイライラしちゃいました。

解説

getBytes()は文字列をバイト配列に変換する。あまりJavaの事は分からないけど、内部文字コードが例えばUnicodeだったとしたら、文字列リテラル*1どの文字コードで書いていても、getBytes()で指定した文字コードエンコードして、そのバイト配列にして返ってくる。多分だけど、外部から入力された文字列データであっても、Javaの世界に入った時点*2で、同じ様にgetBytes()では変換して得たい文字コード名を指定するんじゃないだろうか。
で、そのバイト配列をStringクラスのコンストラクタに渡すと、その文字コードな文字列になる。
getBytes("EUC_JP")だったら、バイト配列はEUC-JPでエンコードしたデータを1バイトずつ配列に入れるって事なので、そのままくっつければEUC-JPの文字列になるはずだけど、恐らくは念のため第2引数で文字コードを指定しておくと無難という事かな。

補足

次の各表は、Java SE 6 でサポートされているエンコーディングセットを示します。新しい java.nio API で使用される正準名は、多くの場合、java.io API および java.lang API で使用される名前とは異なります。

http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/intl/encoding.doc.html

なんかAPIによって、文字コード名がちょっと違うらしい。java.nioというのがなんだか良く知らないけど、Stringクラスはjava.lang.Stringなので、java.langの方になるはず。

java.nio java.lang
EUC-JP EUC_JP
UTF-8 UTF8

MySQLutf-8じゃなくてutf8で間違えやすいなと思ってたけど、Javaもそうらしい。あ、Perluse utf8ってのがあるか。とにかく文字コード名がちょっと間違えやすいです。

余談

もしかしたら、Javaでは文字列の文字コードを変換して変数に入れるみたいな事は、普通やらないのかもしれない。今回はmayaaのテンプレート内で、どうしても1ヶ所文字コードを変更したい所があって、苦肉の策でやりました。
Javaはあまりというか全然分からないので、もし間違いとかあったら、教えてもらえると助かります。

*1:つまりソースコード

*2:Stringオブジェクトになった時点