|
|
Javaソースファイルのエンコーディング |
H.Kamifuji . |
プログラムの中に日本語が含まれている場合などにプログラムを保存する時の文字コードの設定について確認していきます。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 現在(2021/08)では、JDK-16.0.2 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2021/11)では、JDK-17.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2023/04)では、JDK-20.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2024/10)では、JDK-20.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 |
|
プログラムを作成し保存した後、プログラムをコンパイルします。この時、ソースファイルに日本語が含まれている場合には文字コードについて考慮する必要があります。 Javaでは使用している環境に応じてデフォルトのエンコーディングが決まっており、特に指定しない場合には環境毎のデフォルトエンコーディングを使ってプログラムが保存されていると考えてコンパイルを行います。 ご自分の環境のデフォルトエンコーディングを調べるには次の簡単なプログラムを実行して下さい。 サンプルプログラム下記のサンプルを実行してみよう。import java.util.Properties; import java.util.Enumeration; class JSample1_1{ public static void main(String args[]){ System.out.println(System.getProperty("file.encoding")); } }上記をコンパイルした後で実行すると次のように表示されます。 Windows の場合は、 C:\JSample\encoding> java JSample1_1 MS932 C:\JSample\encoding>Linux Gnome の場合は、 [xxxxxxxx@pppppppppp Encoding]$ java JSample1_1 UTF-8 [xxxxxxxx@pppppppppp Encoding]$ Windows環境では「MS932」と表示されます。つまり特に指定しなかった場合、Windows環境ではプログラムのソースファイルはMS932の文字コードを使って記述されていると考えます。 よってWindows環境であればソースファイルを保存する時に文字コードでShift_JISを指定しておけば、ソースファイルに日本語が含まれていても正常に処理されます。
MS932とShift_JISは非常に似ている文字コードですが実際には別々の文字コードです。ただWindows環境の多くのテキストエディタでは保存する時に「MS932」は選択肢にありません。またテキストエディタでShift_JIS(に類する文字コード)を指定して保存すると、実際にはMS932で保存している場合もあります。
もしソースファイルをUTF-8など別の文字コードで保存したい場合には、コンパイルの時にソースファイルで使用している文字コードを教えてあげる必要があります。次のページで文字コードを指定する方法を確認します。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample1_2{ public static void main(String args[]){ System.out.println("今日もいいお天気ですね"); } }上記を文字コードに Windows では、Shit_JIS を Linux では、UTF-8 を指定して保存します。そして次のようにコンパイルを行います。 javac JSample1_3.java上記をコンパイルした後で実行すると次のように表示されます。 Windows の場合は、 C:\JSample\encoding> java JSample1_1 今日もいいお天気ですね C:\JSample\encoding>Linux Gnome の場合は、 [xxxxxxxx@pppppppppp Encoding]$ java JSample1_1 今日もいいお天気ですね [xxxxxxxx@pppppppppp Encoding]$問題なく実行できました。 ではもう一つ試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample1_3{ public static void main(String args[]){ System.out.println("今日もいいお天気ですね"); } }上記を文字コードに Windows では、UTF-8 を Linux では、Shit_JIS を指定して保存します。そして次のようにコンパイルを行います。 javac JSample1_3.java上記をコンパイルした後で実行すると次のように表示されます。 Windows の場合は、 ![]() エラーとなりコンパイルできませんでした。 Linux Gnome の場合は、 [wwwadmin@kamifuji18 Encoding]$ javac JSample1_3.java JSample1_3.java:3: エラー: この文字は、エンコーディングUTF8にマップできません System.out.println("�������������V�C�ł���"); ^ JSample1_3.java:3: エラー: この文字は、エンコーディングUTF8にマップできません System.out.println("�������������V�C�ł���"); ^ JSample1_3.java:3: エラー: この文字は、エンコーディングUTF8にマップできません System.out.println("�������������V�C�ł���"); 省略 エラー18個 [wwwadmin@kamifuji18 Encoding]$エラーとなりコンパイルできませんでした。 このようにソースコードの文字コードと、コンパイル時にJavaが認識している文字コードが一致していないと正常に動作させることはできません。 |
Javaで環境毎に設定されているエンコーディングと異なる文字コードでソースコードを保存した場合、コンパイル時にソースコードの文字コードを指定する必要があります。 文字コードを指定するには「-encoding」オプションを使います。 javac -encoding エンコーディング名 ソースファイル名エンコーディング名にはソースコードを保存した文字コードを指定して下さい。 JDK6の場合に指定可能な文字コードは「サポートされているエンコーディング」にて参照できます。ここでは日本語環境で多く使われるエンコーディングを一部紹介します。
文字コード毎に二通りの記述方法があります。正式な名前は1列目のようですが2列目に記載されているものでも構いません。 Windows の場合、例えばソースファイルを文字コードとしてUTF-8を使って保存した場合、次のようにコンパイルを行います。 javac -encoding UTF-8 sample.javaLinux の場合、例えばソースファイルを文字コードとしてShift_JISを使って保存した場合、次のようにコンパイルを行います。 javac -encoding Shift_JIS sample.java他の文字コードの場合も同様です。 サンプルプログラム下記のサンプルを実行してみよう。class JSample2_1 { public static void main(String args[]){ System.out.println("今日もいいお天気ですね"); } }上記を文字コードに Windows では、UTF-8 を Linux では、Shit_JIS を指定して保存します。そして次のようにコンパイルを行います。 Windows の場合は、 javac -encoding UTF-8 sample2_1.javaLinux の場合は、 javac -encoding Shift_JIS sample2_1.java前のページではエラーが表示されましたが、今回は何も表示されずコンパイルが成功しました。では実行してみます。 Windows の場合は、 C:\JSample\encoding> java JSample2_1 今日もいいお天気ですね C:\JSample\encoding>Linux Gnome の場合は、 [xxxxxxxx@pppppppppp Encoding]$ java JSample2_1 今日もいいお天気ですね [xxxxxxxx@pppppppppp Encoding]$問題なく実行できました。 |
native2ascii は、JDK9(Java9) で廃止になりました。 nkf を利用して、コード変換してください。nkf は、nkf をインストールを参照してください。 ここまで見てきた通りプログラムの中にASCII文字以外の日本語などが含まれている場合、保存された文字コードに合わせてコンパイル時に文字コードを指定する必要があります。 そこでソースコードの中の日本語の部分を全てUnicode コード(\udddd 表記)に変換することによって、ソースコードから日本語の部分を取り除くことができます。その結果としてどのような環境であってもソースファイルの文字コードを気にすることなくコンパイルを行うことができます。 日本語を一つ一つUnicodeに変換することは大変ですが、その為のツールとしてnative2asciiが用意されています。使い方は次のようになります。 native2ascii 元のファイル 変換後のファイル変換元のファイルに含まれる日本語部分をUnicodeコードに変換し、変換後のファイル名として出力します。ここで変換元のファイルが環境毎の決まっているデフォルトのエンコーディング以外で保存されている場合は、次のように文字コードを指定して下さい。 native2ascii -encoding エンコーディング名 元のファイル 変換後のファイルどのように変換されるのかは次のサンプルを参照して下さい。 では実際に試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample3_1{ public static void main(String args[]){ System.out.println("こんにちは"); System.out.println("お元気ですか"); } }上記を文字コードにUTF-8を指定して保存します。そして次のようにnative2asciiを使って変換します。 上記をコンパイルした後で実行すると次のように表示されます。 native2ascii -encoding UTF-8 JSample3_1.java JSample3_3.java では変換されたJSample3_3.javaを確認してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample3_1 { public static void main(String args[]){ System.out.println("\u3053\u3093\u306b\u3061\u306f"); System.out.println("\u304a\u5143\u6c17\u3067\u3059\u304b"); } }変換前のソースファイルの中に含まれていた日本語の部分が\udddd 表記に置き換えられています。ではこのファイルのコンパイルを行ってみます。(ファイル名が変更されていますので、クラス名もJSample3_1からJSample3_3に変更しておく必要があります)。 javac JSample3_3.java C:\JSample\encoding> javac JSample3_3.java C:\JSample\encoding>ソースファイル内にはASCIIとUnicodeコードしか存在しませんので保存された文字コードを気にせずコンパイルすることができます。では実行も行ってみます。 C:\JSample\encoding> java JSample2_1 こんにちは お元気ですか C:\JSample\encoding>実行結果は変換前でも変換後でも変わりはありません。 可読性が悪くなりますので通常はこのような変換を行う必要はないかもしれませんが、様々な環境でコンパイルされるソースコードを配布したい場合などには便利かもしれません。 元に戻す同じツールを使うことでUnicode コード(\udddd 表記)形式で記述されたものを日本語に戻すことができます。次のように行います。native2ascii -reverse 元のファイル 変換後のファイル元のファイルに含まれているUnicode コード(\udddd 表記)形式で記述された部分を日本語に変換し、ファイルとして出力します。この時変換後のファイルの文字コードを指定することができませんでしたので環境毎のデフォルトエンコーディングを使って変換されます。 native2ascii は、Linux など UTF-8 をネイティブにしている場合は、無用のツールのようだ! |
|