Java中的字符编码

3

在Eclipse中,我将默认编码更改为ISO-8859-1。然后我写了以下内容:

String str = "Русский язык ";
PrintStream ps = new PrintStream(System.out, true, "UTF-8");
ps.print(str);

我应该正确打印String,因为我指定了UTF-8编码。但是,它并没有打印出来。


但是你在Eclipse中设置了什么?源代码文件使用的默认编码方式吗?如果是这样,那么这与Java运行时的默认编码方式PrintStream无关。我想知道字符“Русский язык”怎么可能保存在ISO-8859-1中。Eclipse是否会自动转换为\uxxxx语法? - Marko Topolnik
默认编码仅为UTF-8,我将其更改为ISO-8859-1。然后使用PrintStream ps = new PrintStream(System.out,true,“UTF-8”); 它应该打印Unicode字符,但没有打印。将默认编码更改回UTF-8后,它可以正常工作。那么,使用PrintStream ps = new PrintStream(System.out, true, "UTF-8")来更改默认编码有什么用处呢? - Ritesh Kaushik
OP,当你说“默认编码”时,你到底是什么意思?具体指的是哪个Eclipse设置?顺便说一下,我刚刚尝试将源代码编码设置为ISO-8859-1并保存带有该字符串的文件,结果出现错误,说明这些字符无法被所选的编码表示。因此,请问OP,你到底指的是哪个Eclipse设置? - Marko Topolnik
@MarkoTopolnik 在Eclipse中,您可以选择源文件的编码。 - Matteo
亚马克,我已经将Java文件属性更改为ISO-8859-1,如果编码为ISO-8859-1,则Eclipse无法保存Unicode字符。因此,在Unicode字符的位置上打印了一些垃圾字符。但是在PrintStream构造函数中,我提到了UTF-8编码,但它没有打印出那些Unicode字符。如果这是一个愚蠢的问题,我向您道歉,我只是想得到一个解决方案。 - Ritesh Kaushik
显示剩余3条评论
4个回答

4

ISO-8859-1 字符编码只支持 0 到 255 范围内的字符,其他字符将会被转换成“?”。


谢谢回复,彼得。但是在PrintStream构造函数中,我将编码设置为UTF-8? - Ritesh Kaushik
1
但是显示器假定您正在编写ISO-8859-1,因为这是您设置的。它必须将您从PrintStream生成的字节转换回字符。 - Peter Lawrey

4
如果您将源文件(.java文件)保存为ISO-8859-1,则str将由javac使用ISO-8859-1进行编码。您的问题不在于创建PrintStream:您要打印的str从一开始就是错误的。

@MarkoTopolnik 当然有。我曾经遇到过完全相同的问题。Eclipse将文件保存为ISO-8859-1,如果您检查编译类的字节码,您将找不到您期望的内容。在意识到问题不在Hibernate、PostgreSQL中而仅仅是测试文件的编码之前,我在一个集成测试中搜索了几天的编码问题。 - Matteo

0

是的,看起来你发送输出的终端不支持这种编码。

如果你正在运行Eclipse,你可以按照以下步骤设置编码:

  • 在“运行配置”中...->常规 ->编码 ->其他
  • 选择UTF-8

谢谢回复,原来的编码只有UTF-8,我改成了ISO-8859-1。然后使用PrintStream ps = new PrintStream(System.out, true, "UTF-8");应该可以打印Unicode字符,但是没有打印出来。将默认编码改回UTF-8后,它就可以工作了。那么使用PrintStream ps = new PrintStream(System.out, true, "UTF-8");更改默认编码有什么用呢? - Ritesh Kaushik
编码将字节转换为特定字符,但您的“终端”必须设置正确以正确解释它们。 - Reimeus

0

你基本上是告诉PrintStream编写器期望输入字符为UTF-8编码,并将其作为UTF-8输出。没有转换。如果您将IDE设置为使用ISO-8859-1作为文件的字符编码,该文件包含输入字符串,那么您将ISO-8859-1编码的字符传输到期望UTF-8的编写器中。因此,编写器将接收到的字节视为UTF编码的字符,这将导致数据垃圾。

要么将IDE设置为以UTF-8编码源文件并检查字符是否正确显示和存储,要么告诉编写器将它们视为ISO-8859-1,两种方法都可以。


这个答案混淆并将源文件编码与运行时编码混为一谈。它们彼此没有任何关系,两者之间也没有转换。Java字符串在抽象意义上由Unicode字符组成,它们没有以任何方式进行编码。 - Marko Topolnik
部分正确。是的,Java内部使用UTF16编码。但是,如果IDE将(Unicode字符)转换为磁盘上的ISO字节表示形式,则Java字符串中会出现混乱的字符。这样,当打印时,它们会导致运行时中的“非”UTF-16字符。JVM如何能够确定源文件中的输入字符串是如何编码的?它只读取字节,而在这种情况下,这些字节是用于ISO而不是UTF的代码。 - Tobias N. Sasse
不,Java字符并非以UTF-16编码,它们只支持相同的字符集。例如,它们的大小端未定义。它们不会分解成两个字节。 - Marko Topolnik
这是因为该语言内部字符表示使用UTF-16编码,参见(相当古老但几乎确定未更改)Javadoc Charset - Tobias N. Sasse
是的,关于补充字符,UTF-16 有更高级别的编码方式。这全部都是以 16 位字为单位的。请注意,这些 16 位字没有固有的字节编码,而字节编码正是我们正在讨论的主题。 - Marko Topolnik

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