使用带BOM的UTF8编码的Java源代码进行编译(javac)

24

你好,感谢阅读我的帖子。

我的问题如下:我想使用“javac”编译一个Java源文件,该文件采用UTF-8编码并带有BOM(操作系统为WinXP)。

以下是我的步骤:

1)使用“记事本”创建一个文件,并选择UTF-8编码。

dos> notepad Test.java
"File -> Save as..."
File name   : Test.java
Save as type: All Files
Encoding    : UTF-8
Save

2) 在该文件中创建一个Java类,并像1)中那样保存该文件。

public class Test
{
    public static void main(String [] args)
    {
        System.out.println("This is a test.");
    }
}

3)可视化文件的十六进制版本(第一行)

dos> xxd Test.java | head -1
0000000: efbb bf70 7562 6c69 6320 636c 6173 7320  ...public class

注意: ef bb bf 是UTF-8编码的BOM (UTF-16编码的BOM为 FE FF)。

4) 尝试使用"javac"编译这段代码。

dos> javac -encoding utf8 Test.java
Test.java:1: illegal character: \65279
?public class Test
^
1 error

注意:65279是BOM的十进制版本。

我的问题如下:如何在以下情况下使编译工作正常:

  • 保持UTF-8编码
  • 同时保留BOM?

谢谢您的帮助,最好的问候。

Léa


4
没错:你必须删除BOM。它在UTF-8中没有任何作用,所以这当然是一个错误。这是一个长期存在的微软漏洞。绝对不要在UTF-8中放置BOM!!!!! - tchrist
你好。感谢你的回答。 我使用"Notepad++"将文件编码为"UTF8 without BOM"。 现在使用"javac"编译代码可以正常工作了。 - Léa Massiot
8
Unicode标准允许在UTF-8中使用BOM,因此如果您希望使用它,可以将其放置在那里。为什么要这样做是另一个故事,但javac应该会处理它。 - Sled
可能是重复的问题:如何编译以"UTF-8"编码的Java源文件? - Joe
3个回答

36

剪辑BOM,然后使用javac -encoding utf8 x.java


这解决了我的javac编译问题。但是现在Windows10控制台仍然显示未知字符,比如"???????????"。 - Manishoaham
据我了解,chcp 65001 可以帮助您在控制台中显示正常的字符。 - el fuego
尝试了这个,问题仍未解决。开放的问号“?????”转换为方框问号。Windows控制台仍然无法识别文本。这里显示正确的内容:लोकसभा के चुनावी रण में सत्तारूढ़ भाजपा की ओर से सिर्फ नरेन्द्र मोदी ही दिखाई दे रहे हैं। - Manishoaham
这是我至少三个月来一直没能解决的问题。感谢stackoverflow! - Petr Fořt Fru-Fru

19
这不是你的文本编辑器的问题,而是javac的问题!Unicode规范表示在UTF-8中BOM是可选的,并没有说它是禁止的!如果BOM存在,那么javac必须处理它,但实际上它没有处理。事实上,在UTF-8文件中使用BOM有助于区分ANSI编码文件和Unicode编码文件。建议的解决方案是删除BOM,但这只是一种解决方法,而不是正确的解决方法。这个错误报告表明这个“问题”永远不会被修复:https://web.archive.org/web/20160506002035/http://bugs.java.com/view_bug.do?bug_id=4508058。由于这个主题在“javac BOM”搜索结果中排名前两位,我把它放在这里供未来读者参考。

2
实际上,你提到的 bug 与 UTF-8 解码器有关;它与编译器是否可以被修改以检测和丢弃 Java 源文件中的任何 BOM 无关,但编译器确实可以并且应该这样做。 - Lawrence Dol

-1

https://dev59.com/6Gkw5IYBdhLWcg3wkLMX#28043356

实际上,在UTF-8文件中使用BOM有助于区分ANSI编码文件和Unicode编码文件。

实际上

  • BOM并不是用来区分ANSI和Unicode的。不要故意使用一个不是为此设计的功能。

  • UTF-8被有意设计成与ANSI向后兼容,因此处理格式化文本的大量代码仅依赖于0..127字节(XML、JSON等),应该可以正确地处理UTF-8编码的文本而无需任何修改。


请注意,这仅适用于字节级兼容性,在使用UTF-8替换ANSI时,字符级计算将出现错误。 - Nashev
1
UTF-8仅向后兼容_ASCII_(7位范围,0x0 - 0x7F),而不是_ANSI_(ASCII的扩展,还定义了8位范围内的字符,0x80 - 0xFF,该范围与UTF-8不兼容)。是的,在UTF-8文件中使用BOM可用于将其与ANSI(或OEM,...)文件区分开来。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接