9.

javac「この文字はエンコーディング[文字コード]にマップできません」の原因と対処

編集
この記事の要点
  • javac がソースファイルの文字コードを誤認している警告。Windows 既定の MS932 (Shift_JIS) で UTF-8 ソースを読もうとして発生
  • 対処は javac -encoding UTF-8 *.java でエンコーディングを明示
  • Maven は project.build.sourceEncoding=UTF-8 プロパティ、Gradle は compileJava.options.encoding="UTF-8"
  • 実行時の文字化けは別問題: java -Dfile.encoding=UTF-8(Java 18+ は既定 UTF-8)
  • IDE 側も BOM 無し UTF-8 に統一(IntelliJ: File Encodings、Eclipse: Preferences → General → Workspace)
  • 警告は無視せず潰す: マップできない文字は実際に文字化けする(コメント・文字列リテラル両方)

このエラーの典型

C:\src> javac Hello.java
Hello.java:3: 警告: この文字は、エンコーディングMS932にマップできません。
        System.out.println("?????????");
                            ^
Hello.java:5: 警告: この文字は、エンコーディングMS932にマップできません。
        // ?????????????????
           ^
警告4個

原因: Hello.java は UTF-8 で保存されているが、javac は OS 既定の MS932 (Shift_JIS) で読もうとしている → UTF-8 のバイト列を Shift_JIS として解釈できず警告。

対処 1: コマンドラインで -encoding 指定

# UTF-8 ソースを UTF-8 として読ませる
javac -encoding UTF-8 Hello.java

# 複数ファイル
javac -encoding UTF-8 -d build src/**/*.java

# Java 18 以降は javac 既定が UTF-8 になったので不要だが、
# 移植性を考えると明示推奨
javac --release 17 -encoding UTF-8 Hello.java

対処 2: 環境変数で固定

# Linux / macOS の bash / zsh
export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"
export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8

# Windows PowerShell
$env:JAVA_TOOL_OPTIONS = "-Dfile.encoding=UTF-8"

# Windows コマンドプロンプト(コードページも変える)
chcp 65001
set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

対処 3: Maven



    
        
        UTF-8
        UTF-8
        17
    

    
        
            
                maven-compiler-plugin
                3.11.0
                
                    UTF-8
                
            
            
                maven-resources-plugin
                
                    UTF-8
                
            
        
    

対処 4: Gradle

// build.gradle
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}
tasks.withType(Javadoc) {
    options.encoding = 'UTF-8'
}
tasks.withType(Test) {
    systemProperty 'file.encoding', 'UTF-8'
}

// Kotlin DSL (build.gradle.kts)
tasks.withType().configureEach {
    options.encoding = "UTF-8"
}

対処 5: IDE 設定

IDE設定場所
IntelliJ IDEAFile → Settings → Editor → File Encodings → Global / Project / Default を全部 UTF-8、Transparent native-to-ascii conversion はオフ
EclipseWindow → Preferences → General → Workspace → Text file encoding: UTF-8、+ Project Properties → Resource でも UTF-8
VS Codefiles.encoding: utf8、files.autoGuessEncoding: true
NetBeansTools → Options → Miscellaneous → Files → Default Encoding: UTF-8

実行時の文字化けは別問題

コンパイル時に解決しても、実行時の標準出力が化けるケースがあります:

# 実行時のデフォルトエンコーディング指定
java -Dfile.encoding=UTF-8 Hello

# JAVA_TOOL_OPTIONS は java / javac 両方に効く
export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8"

# Java 18+ は既定 UTF-8 (JEP 400)
# それ未満は明示が必要

# Windows コマンドプロンプトでは
chcp 65001
java -Dfile.encoding=UTF-8 Hello

BOM 付き UTF-8 の罠

Windows の「メモ帳」で保存するとBOM (0xEF 0xBB 0xBF) が先頭に付くことがあり、javac はこれを解釈できずエラー:

Hello.java:1: エラー: 不正な文字: ''
?package com.example;
^

対処: BOM 無し UTF-8 で保存。VS Code / IntelliJ / sublime はメニューから設定可。

確認: ファイルの実エンコーディング

# Linux / macOS
file Hello.java
# Hello.java: UTF-8 Unicode text

# hexdump 先頭で BOM 確認
xxd Hello.java | head -1
# 00000000: efbb bf70 ...   ← BOM 付き
# 00000000: 7061 636b ...   ← BOM 無し

# nkf で文字コード判定 (要インストール)
nkf -g Hello.java
# UTF-8

# nkf で変換
nkf -w --overwrite Hello.java   # UTF-8 へ
nkf -s --overwrite Hello.java   # Shift_JIS へ

Java 18 以降の変更 (JEP 400)

Java 18 から標準 charset がプラットフォーム既定から UTF-8 固定に変わりました:

  • Charset.defaultCharset() が UTF-8 を返す
  • FileReader / FileWriter / PrintStream も既定 UTF-8
  • 旧挙動に戻すには -Dfile.encoding=COMPAT
  • 新規プロジェクトは Java 17 LTS / 21 LTS で書くのが安全

FAQ

Q: ? に化けてしまったソースを救えるか
A: 一度文字情報が失われたら復元不能。バックアップから取り直すか、再入力。

Q: log4j / System.out で文字化け
A: ログ設定ファイルに charset 指定、コンソールアペンダのエンコーディングを UTF-8 に。

Q: war 内の properties が化ける
A: maven-resources-pluginencoding を UTF-8 に。ResourceBundle は Java 9 以降 UTF-8 がデフォルト。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. java.lang.NoSuchMethodError
  2. java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
  3. java.lang.UnsupportedClassVersionError
  4. version less than X.X is not supported.
  5. パッケージ~は存在しません
  6. org.apache.jasper.JasperException: ...The jsp:param action must not be...
  7. java.io.FileNotFoundException: ファイル名 (許可がありません)
  8. java.sql.SQLException: Cannot convert value 'YYYY-MM-DD ...' from column n(YYYY-MM-DD ...) to TIMESTAMP.
  9. 警告: この文字は、エンコーディング[文字コード]にマップできません
  10. java.text.ParseException: Unparseable date
  11. Unsupported major.minor version 52.0
  12. エンティティ" ... "への参照は';'デリミタで終了する必要があります。
  13. java.math.BigDecimal cannot be cast to java.lang.String