Akira's Blog

神奈川在住のITエンジニアの雑記です。主にプログラミング(Perl, Java など)やネットワーク技術についての小ネタを、ちょっとずつ書いていきます。

Javaの内部の文字コード

Javaの内部の文字コードUTF-16 である。

なので、Javaのプログラムが外部から読み込んだ SJISUTF-8などの文字列は、JavaのStringオブジェクトになる際に (内部コードである) UTF-16 に変換される。

例えば、以下のサンプルプログラムの通り、(外部文字列に見立てた)「あいう」という文字列に対して、Windows-31J としてバイト列を作成したもの(bytesWin31J)と、UTF-8 としてバイト列を作成したもの(bytesUTF8)は、当然であるが異なっている。
一方で、各々をもとに生成したStringオブジェクト(stringFromWin31J, stringFromUTF8)については、ともに中身の文字列が UTF-16 に変換されているため、同じものになっている。

import java.io.UnsupportedEncodingException;

public class testInternalCode {

    public static void main(String[] args) {
        String str = "あいう";
        try {
            byte[] bytesWin31J = str.getBytes("Windows-31J");
            byte[] bytesUTF8   = str.getBytes("UTF-8");

            dumpHexString(bytesWin31J);  // 82 a0 82 a2 82 a4 
            dumpHexString(bytesUTF8);    // e3 81 82 e3 81 84 e3 81 86 

            String stringFromWin31J = new String(bytesWin31J, "Windows-31J");
            String stringFromUTF8   = new String(bytesUTF8,   "UTF-8");

            if (stringFromWin31J.equals(stringFromUTF8)) { // True
                System.out.println("stringFromWin31J is same as stringFromUTF8");
            }

            for (char c : stringFromWin31J.toCharArray()) {
                System.out.print(Integer.toHexString(c) + " "); // 3042 3044 3046 (UTF16での "あいう")
            }
            System.out.println("");

            for (char c : stringFromUTF8.toCharArray()) {
                System.out.print(Integer.toHexString(c) + " "); // 3042 3044 3046 (UTF16での "あいう")
            }
            System.out.println("");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private static void dumpHexString(byte[] bytes) {
        for (byte b : bytes) {
            System.out.printf("%02x ", b);
        }
        System.out.println();
    }
}