Java Strings中的字符“æ”,“ø”“æ”(Windows)

时间:2013-11-13 15:16:32

标签: java utf-8

由于某种原因,使用Scanner类分配字母å的字符串不等于使用“正常”方式分配å的字符串: String a = "å" - 为什么?

import java.util.*;

public class UTF8Test {
public static void main(String [] args) {

    String [] Norge = {"løk", "hår", "vår", "sær", "søt"};

    Scanner input = new Scanner(System.in);

    String  test = input.nextLine();  //I enter løk here
    System.out.println(test);
    System.out.println(Norge[0]);

    for(int i = 0; i < Norge.length; i++) {
        if(Norge[i].equals(test) ) {
            System.out.println("YES!!");
        }
    }
}
}

编译器将显示:

LOK

LOK

l├©ķ

4 个答案:

答案 0 :(得分:7)

如果您的唯一要求是能够使用UTF8Test类名所指示的UTF-8 无处不在,那么您的主要错误是您正在使用Windows命令控制台进行编译并运行您的Java程序。 ├© ø形式的System.out.println(new String("ø".getBytes("UTF-8"), "CP850")); 强烈建议您使用mojibaked编码来编译Java源代码文件。作为证据,请在支持UTF-8的环境中运行:

├©

这会打印ø。这反过来强烈暗示您使用Windows命令控制台来编译Java源代码文件,因为这是目前唯一默认使用CP850的常用环境。但是,Windows命令控制台支持UTF-8。

当您在文本编辑器中使用UTF-8编码保存(从字符转换为字节)源代码文件时,0xC3字符将变为字节0xB8和{{1} }(作为证据,见CP850)。当您运行javac UTF8Test.java时,基本上使用CP850编码读取UTF-8保存的源代码文件(从字节转换为字符)。字节0xC30xB8在此编码中表示字符©(作为证据,请参阅"UTF-8 (hex)" entry in U+00F8 character info)。这完全解释了您的初始问题。

是的,您可以通过javac参数指示-encoding UTF-8使用UTF-8读取源代码文件。但是,Windows命令控制台本身并不支持UTF-8风格的输入和输出。当您使用-encoding UTF-8重新编译时,您仍然会获得mojibaked输出,因为命令控制台无法正确表示UTF-8输出。我在这里尝试了,而且我得到了学位符号:

løk
l°k

如果您打算在任何地方使用UTF-8 并且希望坚持使用Windows命令控制台作为输入/输出环境,则无法解决此问题。基本上,您需要一个支持UTF-8的输入/输出环境。像Eclipse和Netbeans这样的体面IDE就是这样的。或者,如果您打算将其作为支持UTF-8的独立程序运行,则应优先使用CP850 codepage layout而不是无GUI的控制台程序。

答案 1 :(得分:3)

默认情况下,在Windows上,java编译器使用“平台默认编码”解释其所有源文件。根据您运行编译器的环境,这可能是ISO-8859-1,CP1252,UTF-8或任何其他编码。

如果您使用的编辑器实际上是使用UTF-8编码您的java源文件,但编译器正在使用其他编码读取这些源文件,那么您所有硬编码字符串的内容可能会被搞砸(正如您所经历的那样) )。要解决此问题,请确保将java源文件保存为“platform default encoding”,或者设置java编译器将源文件解释为UTF-8。

尝试使用javac -encoding UTF-8 UTF8Test.java调用您的编译器。如有必要,请确保将UTF-8替换为编辑器用于保存源文件的任何内容。

答案 2 :(得分:3)

如果您想要一个带有特殊字符的字符串文字,可以尝试使用Unicode转义符:

String [] Norge = {"l\u00F8k", "h\u00E5r", "v\u00E5r", "s\u00E6r", "s\u00F8t"};

虽然在源代码中包含特殊字符(至少在java中)并没有错,但在某些情况下,它可能会导致配置不当的编辑器,编译器或终端出现问题;就个人而言,我个人完全没有使用特殊字符。

顺便说一下,你也可以在java源代码的其他地方使用Unicode转义,包括javadoc注释,类,方法和变量名。

如果从命令行进行编译,则可以使用-encoding选项将UTF-8作为参数,将编译器配置为接受UTF-8。像这样:

javac -encoding UTF-8 ...

您可能还会发现此问题很有用:Special Character in Java


您可以考虑使用externalizing the strings作为解决问题的替代方法。 Eclipse提供了一种自动执行此操作的方法,但它基本上只接受所有文字字符串,将它们放在一个单独的文件中,并从该文件中读取以获取相应的字符串。这也允许您创建程序的翻译,通过使用所有字符串的翻译创建不同的文件,或者重新配置应用程序消息而无需重新编译。


编辑:我只是尝试自己编译并运行它(在eclipse中),我没有提到你的问题。因此,您的特定设置可能存在问题。

当我重新配置它以将代码编译为US-ASCII时,它会两次输出l?k

当我重新配置它以将代码编译为UTF-8时,输出为løkløk

当我将其编译为UTF-16时,输出为þÿ l ø kløk,但我无法从终端复制þÿ l ø k中的空格:它会让我复制前两个,但休息其余。这可能与您遇到的问题有关 - 它们可能是一些控制字符,在您的情况下会弄乱它。

答案 3 :(得分:1)

如果您在Eclipse中工作,请使用更改控制台编码 “运行”菜单&gt;运行配置..&gt;常用标签(右侧)&gt;在编码面板中>选择其他= UTF-8

enter image description here