広告

Java : コンソールの文字化け対策 (PowerShell)

Java プログラムをコンソールで実行したときに、文字化けが発生して困ったことはありませんでしょうか?
本記事では、Windows のコンソール(PowerShell) で文字化けが発生したときの対処法について解説します。

解説には、以下の環境を使います。

  • Windows 10 (言語は日本語)
  • PowerShell 7
  • Java 19

ノート

  • もし PowerShell ではなくコマンドプロンプトを使っているのであれば、この機会に PowerShell へと乗り換えることをおすすめします。 最初はとっつきにくいかもしれませんが、慣れてくると便利に使えます。


文字化けする例

実際に文字化けする例を見てみましょう。

次のような Main.java ファイルを用意します。

// Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("テスト");
    }
}

Windows の PowerShell 上で、java コマンドを使い実行します。

PS R:\java-work> java Main.java
繝・せ繝・

"テスト" と表示されることを期待したのですが、文字化けしてしまいました。

※今回は意図的に文字化けを起こす環境でテストしています。
 環境によっては、特に設定を変更せずとも文字化けしないこともあります。

はじめに確認すること

はじめに、

  • PowerShell のコンソール出力で使われる文字コード
  • Java の標準出力(System.out) と標準エラー出力(System.err) で使われる文字コード

をチェックしましょう。

PowerShell で [Console]::OutputEncoding プロパティを確認します。
コンソール出力で使われる文字コードです。

PS R:\java-work> [Console]::OutputEncoding

EncodingName      : Japanese (Shift-JIS)
WebName           : shift_jis
HeaderName        : iso-2022-jp
BodyName          : iso-2022-jp
Preamble          :
WindowsCodePage   :
IsBrowserDisplay  :
IsBrowserSave     :
IsMailNewsDisplay :
IsMailNewsSave    :
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : False
CodePage          : 932

文字コードは Shift-JIS ですね。

次に、Java のプロパティを確認します。
プロパティの一覧には java コマンドの -XshowSettings:properties オプションを使います。

※文字コードに関連するところのみ抜粋しています。

PS R:\java-work> java -XshowSettings:properties -version
Property settings:
    file.encoding = UTF-8
    ...
    native.encoding = MS932
    ...
    stderr.encoding = UTF-8
    stdout.encoding = UTF-8
    ...

これらのプロパティのうち、

  • stdout.encoding : 標準出力(System.out)
  • stderr.encoding : 標準エラー出力(System.err)

に注目しましょう。
今回の例では UTF-8 になっていますね。ちなみに、native.conding に設定されている MS932 は Shift-JIS のことです。

PowerShell は Shift-JIS で表示しようとするけど、Java では UTF-8 で出力しようとして、結果として文字化けした…ということになります。

補足


問題の解決

それでは問題を解決していきましょう。

今回、文字化けが起きている環境の文字コードは、

  • PowerShell : Shift-JIS
  • Java : UTF-8

でした。
この文字コードを統一する必要があります。

PowerShell を UTF-8 に変更するか、Java を Shift-JIS に変更すればよさそうですね。
それぞれ見ていきましょう。

PowerShell の文字コードを変更

PowerShell のプロパティ [Console]::OutputEncoding を UTF-8 に変更します。
UTF-8 Encoding の取得には [System.Text.Encoding]::GetEncoding('utf-8') を使います。

設定前のプロパティです。

PS R:\java-work> [Console]::OutputEncoding

EncodingName      : Japanese (Shift-JIS)
WebName           : shift_jis
HeaderName        : iso-2022-jp
BodyName          : iso-2022-jp
Preamble          :
WindowsCodePage   :
IsBrowserDisplay  :
IsBrowserSave     :
IsMailNewsDisplay :
IsMailNewsSave    :
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : False
CodePage          : 932

UTF-8 に変更します。

PS R:\java-work> [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding('utf-8')
PS R:\java-work> [Console]::OutputEncoding

Preamble          :
BodyName          : utf-8
EncodingName      : Unicode (UTF-8)
HeaderName        : utf-8
WebName           : utf-8
WindowsCodePage   : 1200
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : False
CodePage          : 65001

Java のプロパティはそのままです。

PS R:\java-work> java -XshowSettings:properties -version
Property settings:
    file.encoding = UTF-8
    ...
    native.encoding = MS932
    ...
    stderr.encoding = UTF-8
    stdout.encoding = UTF-8
    ...

これで PowerShell と Java の文字コードを UTF-8 に統一できました。

それでは、Java で日本語を出力してみましょう。

// Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("テスト");
    }
}
PS R:\java-work> java Main.java
テスト

無事に、文字化けなしで日本語が出力されました。

注意

  • 今回の例は PowerShell 7 で実行しています。
    バージョン 7 以外…とくに 7 より古いものでは挙動が変わるかもしれないのでご注意ください。

Java の文字コードを変更

今度は、PowerShell と Java の文字コードを Shift-JIS に統一してみましょう。

PowerShell の [Console]::OutputEncoding プロパティは Shift-JIS のままです。

PS R:\java-work> [Console]::OutputEncoding

EncodingName      : Japanese (Shift-JIS)
WebName           : shift_jis
HeaderName        : iso-2022-jp
BodyName          : iso-2022-jp
Preamble          :
WindowsCodePage   :
IsBrowserDisplay  :
IsBrowserSave     :
IsMailNewsDisplay :
IsMailNewsSave    :
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : False
CodePage          : 932

分かりやすさのために Main.java ファイルを新しく用意します。
stdout.encoding プロパティの値を確認できるようにしています。

// Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("stdout.encoding = " + System.getProperty("stdout.encoding"));
        System.out.println("テスト");
    }
}

まず、そのまま実行してみましょう。

PS R:\java-work> java Main.java
stdout.encoding = UTF-8
繝・せ繝・

stdout.encoding は UTF-8 です。
想定どおり文字化けしました。

次に java のオプションで -Dstdout.encoding=MS932 を指定します。
(MS932 は Shift-JIS です)

PS R:\java-work> java "-Dstdout.encoding=MS932" Main.java
stdout.encoding = MS932
テスト

stdout.encoding は MS932 となり、文字化けせずに出力されました。


PowerShell のフォントを変更

それでも解決しないときは、PowerShell のフォントを確認してみましょう。
日本語に対応していないフォントを使っている可能性があります。

PowerShellプロパティ1

まずは、PowerShell Window の左上のアイコンをクリックします。
メニューが出てくるので "プロパティ" を選択しましょう。

PowerShellプロパティ2

PowerShell のプロパティダイアログが表示されます。
"フォント" タブを選択して、フォントに "MS ゴシック" を指定しましょう。

最後に "OK" ボタンを押してダイアログを閉じます。
文字化けは改善されましたでしょうか…?

補足

file.encoding プロパティ

Java 18 から file.encoding プロパティのデフォルトが UTF-8 になりました。

これは Charset.defaultCharset がデフォルトで UTF-8 になるということです。
また、Java のソースコードも UTF-8 で保存されコンパイルされることが前提となります。(Shift-JIS のファイルをコンパイルすると、デフォルトではコンパイルエラーになります)

Java 18 より前では、file.encoding が環境によっては UTF-8 になったり Shift-JIS になったりと、まちまちでした。
その状況では余計に文字化けを起こしやすい、という環境だったことは否めません。

これがデフォルトで UTF-8 になったので、以前よりかは文字化けが起きにくくなったのではないかなぁ、と思います。
あとは Windows からも Shift-JIS がフェードアウトしてくれれば…

Javaプロパティの一覧

公式ドキュメントによるシステムプロパティ(file.encodingstdout.encoding など) の一覧です。
それぞれのプロパティの詳細は、ページ右側の参照のリンク先に説明があります。

まとめ

Java で文字化けするときは、次の2点を確認しましょう。

  • PowerShell の [Console]::OutputEncoding プロパティ
  • Java の stdout.encodingstderr.encoding プロパティ

これらが違う文字コードを使っているのであれば、それを統一しましょう。


関連記事

ページの先頭へ