Java文件编码异常引发编译断言失败,求字符集配置方案
解决Java动态生成源文件的编码编译错误
问题背景
动态生成Java源文件后编译时出现以下错误:
./named/src/test/test/a/ImplA1.java:1: error: illegal character: '\u009b'
/named/src/test/test/a/ImplA2.java:1: error: illegal character: '\u0080'
问题原因
根源是文件写入编码与编译读取编码不一致:
Files.newBufferedWriter(file)默认使用平台默认字符集写入文件,不同平台默认编码存在差异(如Windows为GBK,Linux/macOS为UTF-8)- 编译器默认以UTF-8读取源文件,当写入编码与读取编码不匹配时,合法字符会被解析为非法控制字符(如\u009b、\u0080)
解决方案
统一文件写入和编译的编码为UTF-8(Java源文件的标准编码),需修改两处代码:
1. 修改JavaSource类的write方法,指定UTF-8编码写入文件
static class JavaSource { final String source; JavaSource(String source) { this.source = source; } /** * Writes the source code to a file in a specified directory. * @param dir the directory * @throws IOException if there is a problem writing the file */ public void write(Path dir) throws IOException { Path file = dir.resolve(getJavaFileNameFromSource(source)); Files.createDirectories(file.getParent()); // 明确指定UTF-8编码写入,消除平台默认编码差异 try (BufferedWriter out = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) { out.write(source.replace("\n", System.lineSeparator())); } } }
2. 修改编译代码,指定编译器用UTF-8读取源文件
在CompilerUtils.compile的参数列表中添加-encoding UTF-8参数,保证与写入编码一致:
if (!CompilerUtils.compile(src, classes.resolve("test"), "--enable-preview", "-source", System.getProperty("java.specification.version"), "-encoding", "UTF-8")) { // 新增编码参数 throw new AssertionError("Compilation didn't succeed!"); }
说明
- 强制使用UTF-8编码符合Java源文件的通用规范,可彻底消除跨平台的编码差异
- 仅修改写入编码或仅修改编译编码无法解决问题,必须保证两端编码完全一致
内容的提问来源于stack exchange,提问作者Navie
相关产品推荐
相关产品推荐

